Teslina Services

Building connectivity solutions

Toulouse, France

@teslina/appssystemkit (0.1.1)

Published 2026-07-28 16:55:36 +02:00 by admin

Installation

@teslina:registry=https://forge.teslina.net/api/packages/Teslina/npm/
npm install @teslina/appssystemkit@0.1.1
"@teslina/appssystemkit": "0.1.1"

About this package

A production-ready design system for Teslina Applications inspired by Fluent design language. Implements consistent UI/UX components using Vue 3, TypeScript, and SCSS with a focus on accessibility, performance, and maintainability.

Teslina AppsSystemKit

A production-ready design system for Teslina Applications inspired by Fluent design language. Implements consistent UI/UX components using Vue 3, TypeScript, and SCSS with a focus on accessibility, performance, and maintainability.

🚀 Quick Start

Installation

# Install dependencies
npm install

# Run development server
npm run dev

# Build for production
npm run build

Basic Usage

<template>
  <div>
    <TslButton variant="primary" @click="handleAction">
      Create Resource
    </TslButton>
    
    <TslInput
      v-model="name"
      label="Name"
      placeholder="Enter name"
    />
    
    <TslBadge variant="success" dot>Active</TslBadge>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import TslButton from './components/base/Button.vue';
import TslInput from './components/forms/Input.vue';
import TslBadge from './components/base/Badge.vue';

const name = ref('');

const handleAction = () => {
  console.log('Action:', name.value);
};
</script>

Project Structure

Teslina_AppsSystemKit/
├── components/           # Vue 3 components
│   ├── base/            # Buttons, Badges, Cards, Avatars
│   ├── forms/           # Inputs, Checkboxes, Selects
│   ├── feedback/        # Alerts, Progress, Spinners, Dialogs
│   ├── navigation/      # Tabs, Breadcrumbs, Menus
│   ├── layout/          # Shell, Rail, Topbar, Subnav
│   ├── modals/          # Wizards and modal dialogs
│   └── widgets/         # Date pickers, file uploads, charts
├── styles/
│   ├── tokens/          # Design tokens (SCSS variables)
│   ├── base/            # CSS variables, reset, typography
│   └── utilities/       # Utility classes
├── pages/
│   └── examples/        # Working demo pages (components, widgets, shell, cloud)
├── layouts/             # Nuxt layouts
├── CLAUDE.md            # AI assistant instructions
└── README.md            # This file

🎨 Design System Overview

Design Principles

1. Neutral First, Accent Rare

The interface lives in grayscale. Blue accent (#0f6cbd) is reserved for primary actions, selection, and links—never decorative.

2. Subtle Depth

Fluent shadows (depth 2→64) separate layers. Flat surfaces are primary; elevation signals interactivity or temporality.

3. Comfortable Density

  • 32px target control height
  • 4px grid system
  • Generous spacing around titles
  • Readable without being sparse

4. Purposeful Motion

  • Short transitions (100–300ms) with deceleration
  • Motion explains state, doesn't distract

Design Tokens

Colors

Brand (Fluent Communication Blue):

$brand-100: #0f6cbd;        // Primary
$brand-90: #115ea3;         // Hover
$brand-80: #0f548c;         // Pressed
$brand-tint-40: #ebf3fc;    // Selected fill
$brand-tint-50: #f6fafe;    // Hover fill

Neutrals:

$neutral-bg-1: #ffffff;     // Card background
$neutral-bg-2: #fafafa;     // Subtle background
$neutral-bg-3: #f5f5f5;     // Canvas
$neutral-bg-4: #f0f0f0;     // Hover
$neutral-fg-1: #242424;     // Primary text
$neutral-fg-2: #424242;     // Secondary text
$neutral-fg-3: #616161;     // Tertiary text
$neutral-fg-disabled: #bdbdbd;  // Disabled text

Status:

$status-success: #0e7c41;
$status-warning-fg: #bc4b09;
$status-danger: #b10e1c;
$status-info: #0f6cbd;

Spacing (4px Grid)

$sp-4: 4px;   $sp-8: 8px;   $sp-12: 12px;
$sp-16: 16px; $sp-20: 20px; $sp-24: 24px;
$sp-32: 32px; $sp-40: 40px; $sp-48: 48px;

Typography Scale

.t-display      // 68px / 600  Hero headings
.t-title1       // 40px / 600  Page titles
.t-title2       // 28px / 600  Section titles
.t-title3       // 20px / 600  Subsection titles
.t-subtitle     // 16px / 600  Card titles
.t-body-strong  // 14px / 600  Emphasized body
.t-body         // 14px / 400  Default body
.t-caption      // 12px / 400  Metadata (muted)
.t-mono         // 12.5px mono  Code/IDs

Border Radius

$radius-sm: 2px;   // Sharp
$radius-md: 4px;   // Standard controls
$radius-lg: 6px;   // Small cards
$radius-xl: 8px;   // Large cards
$radius-circular: 999px;  // Pills, avatars

Shadows (Fluent Depth)

$shadow-2: 0 0 2px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.14);   // Cards at rest
$shadow-8: 0 0 2px rgba(0,0,0,0.12), 0 4px 8px rgba(0,0,0,0.14);   // Menus
$shadow-16: 0 0 2px rgba(0,0,0,0.12), 0 8px 16px rgba(0,0,0,0.14); // Popovers
$shadow-28: 0 0 8px rgba(0,0,0,0.12), 0 14px 28px rgba(0,0,0,0.18);// Flyouts
$shadow-64: 0 0 8px rgba(0,0,0,0.12), 0 32px 64px rgba(0,0,0,0.24);// Dialogs

Motion

$dur-fast: 100ms;     // Hover, color changes
$dur-normal: 200ms;   // Dialogs, focus
$dur-slow: 300ms;     // Panels, wizards

$ease-decel: cubic-bezier(0.1, 0.9, 0.2, 1);    // Entrance
$ease-accel: cubic-bezier(0.7, 0, 1, 0.5);      // Exit
$ease-standard: cubic-bezier(0.33, 0, 0.67, 1); // General UI

📦 Component Catalog

Base Components

TslButton

Purpose: Interactive buttons with multiple visual variants and sizes
Location: components/base/Button.vue
Props: variant (primary|secondary|subtle|outline-accent|danger|link), size (sm|default|lg), disabled, loading, icon, type
Events: click

TslBadge

Purpose: Status indicators with colored variants and optional dots
Location: components/base/Badge.vue
Props: variant (neutral|info|success|warning|danger|important), dot
Events: None

TslCard

Purpose: Content containers with subtle elevation and hover states
Location: components/base/Card.vue
Props: padding, hover, flat
Events: click

TslAvatar

Purpose: User representation with initials, images, and size variants
Location: components/base/Avatar.vue
Props: src, alt, initials, size (sm|default|lg), color
Events: None

TslPersona

Purpose: Combined avatar with user metadata (name, subtitle)
Location: components/base/Persona.vue
Props: name (required), subtitle, src, initials, size, color
Events: None

TslIconButton

Purpose: Compact icon-only button for toolbars and actions
Location: components/base/IconButton.vue
Props: variant, size, disabled, label, type
Events: click


Form Components

TslInput

Purpose: Text input field with label, hint, and Fluent-style focus border
Location: components/forms/Input.vue
Props: modelValue, label, placeholder, hint, error, disabled, type, id
Events: update:modelValue, focus, blur
Notes: error renders in place of hint and adds an error border. Falls through unbound attrs ($attrs) to the <input>; label is linked to the input via id/for (auto-generated with useId() if id isn't passed).

TslCheckbox

Purpose: Boolean selection control with indeterminate state support
Location: components/forms/Checkbox.vue
Props: modelValue, indeterminate, disabled
Events: update:modelValue, change

TslRadio

Purpose: Single selection from a group of options
Location: components/forms/Radio.vue
Props: modelValue, value, name, disabled
Events: update:modelValue, change

TslSwitch

Purpose: Toggle control with animated track for binary choices
Location: components/forms/Switch.vue
Props: modelValue, disabled
Events: update:modelValue, change

TslSelect

Purpose: Dropdown selector with Fluent chevron icon
Location: components/forms/Select.vue
Props: modelValue, label, placeholder, hint, error, disabled
Events: update:modelValue, change
Notes: Options are passed as <option> elements via the default slot, not an options prop.

TslTextarea

Purpose: Multi-line text input with auto-resize support
Location: components/forms/Textarea.vue
Props: modelValue, label, placeholder, rows, disabled
Events: update:modelValue


Feedback Components

TslAlert

Purpose: Message bars for info, success, warning, and error states
Location: components/feedback/Alert.vue
Props: variant (info|success|warning|danger), dismissible
Events: dismiss
Slots: default, icon

TslProgress

Purpose: Linear progress indicator with determinate and indeterminate modes
Location: components/feedback/Progress.vue
Props: value (0-100), max, label, showPercentage, indeterminate, variant, size
Events: None

TslSpinner

Purpose: Loading indicator with size and color variants
Location: components/feedback/Spinner.vue
Props: size (sm|default|lg), variant (neutral|primary|success|danger), label
Events: None

TslDialog

Purpose: Modal dialog with scrim, teleport, and slot support
Location: components/feedback/Dialog.vue
Props: modelValue, title, size, closable, closeOnScrimClick
Events: update:modelValue, close
Slots: default, footer


Navigation Components

TslTabs

Purpose: Horizontal tab navigation with active indicator
Location: components/navigation/Tabs.vue
Props: modelValue, tabs (array of strings)
Events: update:modelValue, change

TslBreadcrumb

Purpose: Hierarchical navigation with separators
Location: components/navigation/Breadcrumb.vue
Props: items (array of {label, to}), separator
Events: click

TslMenu

Purpose: Dropdown and context menu, composed from TslMenuItem/TslMenuDivider children
Location: components/navigation/Menu.vue
Props: modelValue (required, open state), anchorEl, position
Events: update:modelValue, close
Notes: Menu content is slot-based, not driven by an items prop.

  • TslMenuItem (components/navigation/MenuItem.vue) — Props: disabled, danger, shortcut; Events: click; Slots: icon, default
  • TslMenuDivider (components/navigation/MenuDivider.vue) — Visual separator between menu items, no props

TslAppSwitcher

Purpose: Application switcher panel for multi-app navigation
Location: components/navigation/AppSwitcher.vue
Props: apps (array)
Events: None


Layout Components

TslShell

Purpose: Complete application shell with topbar, rail, and content area
Location: components/layout/Shell.vue
Props: None
Slots: topbar, rail, subnav, default
Notes: Internally composes LayoutShellContent.vue (components/layout/LayoutShellContent.vue), which lays out the subnav/default slots — not used directly.

TslTopbar

Purpose: Application header with branding, navigation, and actions
Location: components/layout/Topbar.vue
Props: None
Slots: start, center, end

TslRail

Purpose: Vertical navigation rail, composed of TslRailItem children
Location: components/layout/Rail.vue
Props: None
Slots: default

  • TslRailItem (components/layout/RailItem.vue) — Props: label, to, active; Events: click; Slots: icon

TslSubnav

Purpose: Secondary horizontal navigation below topbar, composed of TslSubnavItem children
Location: components/layout/Subnav.vue
Props: title
Slots: default

  • TslSubnavItem (components/layout/SubnavItem.vue) — Props: label, href, active; Events: click; Slots: icon

Modal Components

TslResourceWizard

Purpose: Multi-step wizard for resource creation workflows
Location: components/modals/ResourceWizard.vue
Props: modelValue
Events: update:modelValue, create
Notes: Wizard steps (components/modals/wizard-steps/Step*.vue — Product, Region, Specs, Options, Settings, Review) are internal to this component and not configurable via props.


Widget Components

DatePicker

Purpose: Single date selection with calendar dropdown
Location: components/widgets/DatePicker.vue
Props: modelValue, label, disabled, weekStartsOn (0-6, defaults to locale-derived week start)
Events: update:modelValue

DateRangePicker

Purpose: Start and end date selection with range highlighting
Location: components/widgets/DateRangePicker.vue
Props: modelValue ({ start: Date, end: Date }), label, disabled, weekStartsOn (0-6, defaults to locale-derived week start)
Events: update:modelValue

MiniCalendar

Purpose: Compact calendar display with event indicators
Location: components/widgets/MiniCalendar.vue
Props: modelValue, events
Events: update:modelValue

TimePicker

Purpose: Time selection with 12/24 hour format support
Location: components/widgets/TimePicker.vue
Props: modelValue, use24Hour
Events: update:modelValue

FileUpload

Purpose: File selection with type filtering and size validation
Location: components/widgets/FileUpload.vue
Props: modelValue, multiple, accept, maxSize, disabled
Events: update:modelValue

FileDropZone

Purpose: Drag-and-drop file upload area
Location: components/widgets/FileDropZone.vue
Props: modelValue
Events: update:modelValue

ColorPicker

Purpose: Color selection with hex, RGB, and HSL support
Location: components/widgets/ColorPicker.vue
Props: modelValue
Events: update:modelValue

ThemeConfigurator

Purpose: Real-time theme customization with token controls
Location: components/widgets/ThemeConfigurator.vue
Props: None
Events: None

Timer

Purpose: Countdown/countup timer with controls
Location: components/widgets/Timer.vue
Props: modelValue (required, seconds)
Events: update:modelValue, complete

Countdown

Purpose: Simple countdown to a target date/time
Location: components/widgets/Countdown.vue
Props: targetDate (required, Date)
Events: None

SkeletonLoader

Purpose: Placeholder loading state for content
Location: components/widgets/SkeletonLoader.vue
Props: variant (text|card|list|table)
Events: None

KanbanBoard

Purpose: Drag-and-drop kanban board for task management
Location: components/widgets/KanbanBoard.vue
Props: modelValue (Column[])
Events: update:modelValue

CircularProgress

Purpose: Circular progress indicator with percentage display
Location: components/widgets/CircularProgress.vue
Props: value (0-100), size, strokeWidth, variant
Events: None

StatsWidget

Purpose: Metric display with title, value, and trend
Location: components/widgets/StatsWidget.vue
Props: title, value, trend, trendLabel, description, format, loading, hover
Events: None

StatusWidget

Purpose: System status display listing multiple status items
Location: components/widgets/StatusWidget.vue
Props: title, items (StatusItem[]), loading
Events: None

ActivityWidget

Purpose: Recent activity feed with timestamps
Location: components/widgets/ActivityWidget.vue
Props: title, items (required), loading
Events: None

QuickActionsWidget

Purpose: Grid of quick action buttons
Location: components/widgets/QuickActionsWidget.vue
Props: title, actions (required), loading
Events: None

WidgetContainer

Purpose: Container wrapper for dashboard widgets
Location: components/widgets/WidgetContainer.vue
Props: title, collapsible, loading, empty, emptyMessage, hover, padding
Slots: default, header, footer, actions

ChartWidget

Purpose: Progress-ring, bar, or sparkline chart visualization
Location: components/widgets/ChartWidget.vue
Props: title, type (progress-ring|bar|sparkline), value, label, barData, sparklineData, loading
Events: None

💡 Examples

This kit includes complete working examples as Nuxt pages under pages/examples/:

  • components-demo.vue — All base, form, and feedback components with interactive states
  • widgets-demo.vue — Date pickers, file uploads, calendars, charts, and dashboard widgets
  • shell-demo.vue — Application shell layout with topbar, rail, subnav, and content areas
  • cloud-demo.vue — Real-world cloud console example with resource creation wizard

Running Examples

npm run dev

Navigate to:

  • http://localhost:3000/examples/components-demo
  • http://localhost:3000/examples/widgets-demo
  • http://localhost:3000/examples/shell-demo
  • http://localhost:3000/examples/cloud-demo

📐 Usage Rules & Patterns

Component Composition

Button Groups:

<div class="flex gap-8">
  <TslButton variant="primary">Save</TslButton>
  <TslButton variant="secondary">Cancel</TslButton>
</div>

Form Fields:

<TslInput
  v-model="name"
  label="Project Name"
  hint="3 to 24 lowercase characters"
  placeholder="ex. tsl-prod-eu"
/>

Status Badges:

<TslBadge variant="success" dot>Running</TslBadge>
<TslBadge variant="warning">Pending</TslBadge>
<TslBadge variant="danger">Failed</TslBadge>

Card Layouts:

<TslCard padding hover>
  <h3 class="t-subtitle mb-8">Title</h3>
  <p class="muted">Description text</p>
</TslCard>

Accessibility Guidelines

All components follow WCAG 2.1 AA standards:

  • Proper semantic HTML elements
  • ARIA labels and roles where needed
  • Keyboard navigation support (Tab, Enter, Space, Arrows)
  • Focus indicators with sufficient contrast
  • Color contrast ratios meet AA requirements (4.5:1 for text)
  • Screen reader compatible announcements
  • Logical tab order

Anti-Patterns to Avoid

No inline styles — Always use classes from design tokens
No !important — Only allowed in utility classes
No hardcoded colors — Use SCSS variables from styles/tokens/_tokens.scss
No magic numbers — Use spacing scale variables ($sp-4 through $sp-48)
No AI-generated clichés — Avoid gradient abuse, unnecessary animations, oversized shadows

🏗️ Architecture Guidelines

Component Structure

Each component follows strict separation of concerns:

<template>
  <!-- Clean, semantic HTML structure -->
  <button :class="buttonClasses" @click="handleClick">
    <slot />
  </button>
</template>

<script setup lang="ts">
import { computed } from 'vue';

// TypeScript interface for props
interface Props {
  variant?: 'primary' | 'secondary';
  size?: 'sm' | 'default' | 'lg';
  disabled?: boolean;
}

// Props with defaults
const props = withDefaults(defineProps<Props>(), {
  variant: 'primary',
  size: 'default',
  disabled: false,
});

// Computed classes
const buttonClasses = computed(() => [
  'tsl-btn',
  `tsl-btn--${props.variant}`,
  `tsl-btn--${props.size}`,
]);

// Event emission
const emit = defineEmits<{
  click: [event: MouseEvent];
}>();

const handleClick = (event: MouseEvent) => {
  if (!props.disabled) {
    emit('click', event);
  }
};
</script>

<style scoped lang="scss">
@use '/styles/tokens/tokens' as *;

.tsl-btn {
  // Use design tokens
  padding: $sp-12 $sp-16;
  border-radius: $radius-md;
  background: $brand-100;
  color: white;
  transition: background $dur-fast $ease-standard;
  
  &:hover {
    background: $brand-90;
  }
  
  &--secondary {
    background: $neutral-bg-1;
    color: $neutral-fg-1;
    border: 1px solid $stroke-1;
  }
}
</style>

Development Rules

  1. One component per Vue file — No separate .scss files
  2. Scoped SCSS within component — All styles in <style scoped lang="scss">
  3. Minimal dependencies — Only import what's necessary
  4. Object-oriented approach — Use classes and TypeScript interfaces
  5. TypeScript interfaces for all props — Proper typing for better DX
  6. Accessibility-first — Keyboard navigation, ARIA, focus management

Design Token Import

@use '/styles/tokens/tokens' as *;

.component {
  padding: $sp-16;              // Spacing
  color: $neutral-fg-1;         // Colors
  border-radius: $radius-md;    // Border radius
  box-shadow: $shadow-2;        // Shadows
  transition: all $dur-fast $ease-standard; // Motion
}

🤖 AI Agent Reference

Quick Component Lookup Table

Component Category Path Primary Props
TslButton base components/base/Button.vue variant, size, disabled, loading, icon
TslBadge base components/base/Badge.vue variant, dot
TslCard base components/base/Card.vue padding, hover, flat
TslAvatar base components/base/Avatar.vue src, initials, alt, size, color
TslPersona base components/base/Persona.vue name, subtitle, src, initials, size
TslIconButton base components/base/IconButton.vue variant, size, label
TslInput forms components/forms/Input.vue modelValue, label, placeholder, hint, error
TslCheckbox forms components/forms/Checkbox.vue modelValue, indeterminate
TslRadio forms components/forms/Radio.vue modelValue, value, name
TslSwitch forms components/forms/Switch.vue modelValue
TslSelect forms components/forms/Select.vue modelValue, label, hint, error (options via default slot)
TslTextarea forms components/forms/Textarea.vue modelValue, rows
TslAlert feedback components/feedback/Alert.vue variant, dismissible
TslProgress feedback components/feedback/Progress.vue value, max, label, indeterminate
TslSpinner feedback components/feedback/Spinner.vue size, variant, label
TslDialog feedback components/feedback/Dialog.vue modelValue, title, size, closable
TslTabs navigation components/navigation/Tabs.vue modelValue, tabs
TslBreadcrumb navigation components/navigation/Breadcrumb.vue items, separator
TslMenu navigation components/navigation/Menu.vue modelValue, anchorEl, position (items via slot)
TslMenuItem navigation components/navigation/MenuItem.vue disabled, danger, shortcut
TslAppSwitcher navigation components/navigation/AppSwitcher.vue apps
TslShell layout components/layout/Shell.vue (slots only)
TslTopbar layout components/layout/Topbar.vue (slots: start, center, end)
TslRail layout components/layout/Rail.vue (slots only)
TslRailItem layout components/layout/RailItem.vue label, to, active
TslSubnav layout components/layout/Subnav.vue title
TslSubnavItem layout components/layout/SubnavItem.vue label, href, active
TslResourceWizard modals components/modals/ResourceWizard.vue modelValue
DatePicker widgets components/widgets/DatePicker.vue modelValue, label, weekStartsOn
DateRangePicker widgets components/widgets/DateRangePicker.vue modelValue, label, weekStartsOn
TimePicker widgets components/widgets/TimePicker.vue modelValue, use24Hour
KanbanBoard widgets components/widgets/KanbanBoard.vue modelValue
Timer widgets components/widgets/Timer.vue modelValue
Countdown widgets components/widgets/Countdown.vue targetDate

File Path Patterns

Components:

components/
  base/         — Buttons, badges, cards, avatars
  forms/        — Inputs, checkboxes, selects, switches
  feedback/     — Alerts, progress, spinners, dialogs
  navigation/   — Tabs, breadcrumbs, menus
  layout/       — Shell, topbar, rail, subnav
  modals/       — Wizards and modal dialogs
  widgets/      — Date pickers, charts, utilities

Styles:

styles/
  tokens/_tokens.scss       — All design tokens
  base/_variables.scss      — CSS custom properties
  base/_reset.scss          — Minimal reset
  base/_typography.scss     — Typography classes
  utilities/_utilities.scss — Utility classes
  main.scss                 — Entry point

Common Import Patterns

Component Import:

<script setup lang="ts">
import TslButton from './components/base/Button.vue';
import TslInput from './components/forms/Input.vue';
import TslCard from './components/base/Card.vue';
</script>

Token Import in SCSS:

@use '/styles/tokens/tokens' as *;

.component {
  padding: $sp-16;
  color: $neutral-fg-1;
  background: $neutral-bg-1;
}

Design Token Categories

Colors: $brand-*, $neutral-*, $status-*, $stroke-*
Spacing: $sp-4 through $sp-48
Typography: .t-display, .t-title1, .t-subtitle, .t-body, .t-caption
Radius: $radius-sm, $radius-md, $radius-lg, $radius-xl, $radius-circular
Shadows: $shadow-2, $shadow-8, $shadow-16, $shadow-28, $shadow-64
Motion: $dur-fast, $dur-normal, $dur-slow + $ease-decel, $ease-accel, $ease-standard

Common Component Patterns

Form Field with v-model:

<TslInput
  v-model="value"
  label="Field Label"
  placeholder="Enter value"
  hint="Helper text"
/>

Dialog with Footer:

<TslDialog v-model="showDialog" title="Confirm">
  <p>Dialog content</p>
  <template #footer>
    <TslButton variant="primary" @click="confirm">OK</TslButton>
    <TslButton variant="secondary" @click="cancel">Cancel</TslButton>
  </template>
</TslDialog>

Card Grid Layout:

<div class="grid gap-24">
  <TslCard padding hover>
    <h3 class="t-subtitle">Title</h3>
    <p class="muted">Description</p>
  </TslCard>
</div>

Dependencies

Dependencies

ID Version
@nuxt/icon ^2.2.3
@nuxtjs/device ^4.0.0
@nuxtjs/i18n ^10.4.0
@nuxtjs/mdc ^0.22.0
nuxt ^4.4.8
vue ^3.5.35
vue-router ^5.1.0

Development Dependencies

ID Version
@iconify-json/fluent ^1.2.50
@iconify-json/svg-spinners ^1.2.4
sass ^1.101.0
Details
npm
2026-07-28 16:55:36 +02:00
3
latest
58 KiB
Assets (1)
Versions (2) View all
0.1.1 2026-07-28
0.1.0 2026-07-28