Komponentenbibliothek
Referenz für die wiederverwendbaren, automatisch importierten Vue-UI-Komponenten aus dem Layer packages/ui.
Owlat enthält eine Reihe wiederverwendbarer Vue-Komponenten in packages/ui/components/ui/.
Wenn Sie diese Komponenten zu einer Oberfläche zusammensetzen, folgen Sie dem Standard zur schrittweisen Offenlegung: Beginnen Sie mit einem Urteil bzw. einer Zusammenfassung und halten Sie tiefergehende Details genau eine Interaktion entfernt.
Überblick
Alle Komponenten folgen diesen Prinzipien:
- Einheitliches Styling - Verwendet Design-System-Tokens aus main.css
- TypeScript - Vollständige Typunterstützung
- Barrierefrei - ARIA-Attribute und Tastaturnavigation
- Automatisch importiert - Ohne explizite Imports verfügbar (Nuxt-Feature)
Button (UiButton)
Vielseitige Button-Komponente mit Varianten und Zuständen.
Props
| Prop | Typ | Standard | Beschreibung |
|---|---|---|---|
variant | string | 'primary' | 'primary', 'secondary', 'outline', 'ghost', 'danger', 'danger-ghost', 'danger-outline' |
size | string | 'md' | 'sm', 'md', 'lg' |
loading | boolean | false | Spinner anzeigen und Button deaktivieren |
disabled | boolean | false | Button deaktivieren |
fullWidth | boolean | false | Button über die volle Breite |
Slots
default- ButtontexticonLeft- Icon vor dem TexticonRight- Icon nach dem Text
Beispiele
<!-- Primary button -->
<UiButton variant="primary">Save</UiButton>
<!-- With loading state -->
<UiButton variant="primary" :loading="isSubmitting">
Submit
</UiButton>
<!-- With icon -->
<UiButton variant="secondary">
<template #iconLeft>
<Icon name="lucide:plus" class="w-4 h-4" />
</template>
Add Item
</UiButton>
<!-- Danger button -->
<UiButton variant="danger">Delete</UiButton>
Input (UiInput)
Texteingabe mit Label, Fehlerzustand und Icons.
Props
| Prop | Typ | Standard | Beschreibung |
|---|---|---|---|
type | string | 'text' | 'text', 'email', 'password', 'number', 'date' |
modelValue | string/number | - | v-model-Wert |
label | string | - | Label-Text |
placeholder | string | - | Platzhaltertext |
error | string | - | Fehlermeldung |
helpText | string | - | Hilfetext (wird angezeigt, wenn kein Fehler vorliegt) |
required | boolean | false | Sternchen für Pflichtfeld anzeigen |
disabled | boolean | false | Eingabefeld deaktivieren |
size | string | 'md' | 'sm', 'md' |
Slots
iconLeft- Icon auf der linken Seite des EingabefeldsiconRight- Icon auf der rechten Seite des Eingabefelds
Beispiele
<!-- Basic input -->
<UiInput v-model="email" label="Email" type="email" placeholder="you@example.com" />
<!-- With error -->
<UiInput v-model="email" label="Email" :error="errors.email" required />
<!-- With search icon -->
<UiInput v-model="search" placeholder="Search...">
<template #iconLeft>
<Icon name="lucide:search" class="w-4 h-4" />
</template>
</UiInput>
Select (UiSelect)
Eigenes Dropdown, aufgebaut aus einem <button>-Trigger und einem schwebenden Menü (kein natives <select>). Beim Öffnen erscheint eine mit einer Transition animierte Liste; der Trigger trägt einen Lucide-Chevron und die ausgewählte Option ein Häkchen-Icon. Das Menü schließt bei einem Klick außerhalb oder mit Escape. Die Komponente ist generisch über T extends string | number.
Props
| Prop | Typ | Standard | Beschreibung |
|---|---|---|---|
options | array | [{ value, label }] | |
modelValue | T | null | null | v-model-Wert (String oder Zahl) |
label | string | - | Label-Text |
placeholder | string | 'Select an option' | Text, der angezeigt wird, wenn keine Option ausgewählt ist |
error | string | - | Fehlermeldung |
required | boolean | false | Sternchen für Pflichtfeld anzeigen |
disabled | boolean | false | Select deaktivieren |
size | string | 'md' | 'sm', 'md' |
Beispiele
<UiSelect
v-model="country"
label="Country"
placeholder="Select a country"
:options="[
{ value: 'us', label: 'United States' },
{ value: 'uk', label: 'United Kingdom' },
{ value: 'de', label: 'Germany' },
]"
/>
Textarea (UiTextarea)
Mehrzeilige Texteingabe mit Zeichenzähler.
Props
| Prop | Typ | Standard | Beschreibung |
|---|---|---|---|
modelValue | string | - | v-model-Wert |
label | string | - | Label-Text |
placeholder | string | - | Platzhaltertext |
rows | number | 4 | Anzahl der Zeilen |
maxLength | number | - | Maximale Zeichenzahl (zeigt einen Zähler) |
resize | string | 'none' | 'none', 'vertical', 'both' |
error | string | - | Fehlermeldung |
required | boolean | false | Sternchen für Pflichtfeld anzeigen |
Beispiele
<UiTextarea
v-model="description"
label="Description"
:rows="4"
:max-length="500"
resize="vertical"
/>
Checkbox (UiCheckbox)
Checkbox mit Label und optionaler Beschreibung.
Props
| Prop | Typ | Standard | Beschreibung |
|---|---|---|---|
modelValue | boolean | false | v-model-Wert |
label | string | - | Label-Text |
description | string | - | Hilfetext unter dem Label |
disabled | boolean | false | Checkbox deaktivieren |
Beispiele
<UiCheckbox v-model="acceptTerms" label="I accept the terms and conditions" />
<UiCheckbox
v-model="newsletter"
label="Subscribe to newsletter"
description="Receive weekly updates about new features"
/>
Switch (UiSwitch)
Umschalter aus Schiene und Griff mit role="switch"-Semantik — das An/Aus-Bedienelement, das in Einstellungen, Präferenzen und Konfigurationskarten verwendet wird. Verwenden Sie UiSwitch für einen gleitenden Schienen-Umschalter und UiToggle für den Umschalter im Icon-Stil; für dreiwertige Feature-Pakete (an/teilweise/aus) behalten Sie ein maßgeschneidertes Bedienelement.
Props
| Prop | Typ | Standard | Beschreibung |
|---|---|---|---|
modelValue | boolean | false | v-model-Wert |
disabled | boolean | false | Den Switch deaktivieren |
label | string | - | Zugänglicher Name — erforderlich, wenn kein sichtbares Label auf den Switch verweist |
Beispiele
<UiSwitch v-model="autoReplyEnabled" label="Enable auto-reply" />
<UiSwitch v-model="featureOn" :disabled="!canToggle" label="Knowledge graph" />
Progress Bar (UiProgressBar)
Fortschrittsbalken mit bestimmtem oder unbestimmtem Verlauf und role="progressbar". Wird für Importe, Versandlimits und jede Arbeit unbekannter Dauer (unbestimmter Durchlauf) verwendet. Berücksichtigt prefers-reduced-motion.
Props
| Prop | Typ | Standard | Beschreibung |
|---|---|---|---|
value | number | 0 | 0–100. Wird ignoriert, wenn indeterminate true ist. |
variant | string | 'brand' | 'brand', 'success', 'warning', 'error' |
indeterminate | boolean | false | Animierter Durchlauf für Arbeit unbekannter Dauer |
size | string | 'md' | 'sm', 'md' (Höhe der Schiene) |
ariaLabel | string | - | Zugänglicher Name, den Screenreader vorlesen |
Beispiele
<UiProgressBar :value="importPercent" :aria-label="`Importing: ${importPercent}%`" />
<UiProgressBar indeterminate variant="brand" aria-label="Discovering messages" />
<UiProgressBar :value="95" variant="warning" size="sm" aria-label="Sending limit" />
Card (UiCard)
Container mit Varianten und Slots.
Props
| Prop | Typ | Standard | Beschreibung |
|---|---|---|---|
padding | string | 'md' | 'none', 'sm', 'md', 'lg' |
variant | string | 'default' | 'default', 'info', 'warning', 'error' |
hoverable | boolean | false | Rahmeneffekt beim Hovern hinzufügen |
clickable | boolean | false | Zeiger anzeigen und Click-Event emittieren |
overflow | string | 'visible' | 'visible', 'hidden' |
Slots
default- Hauptinhaltheader- Kopfbereich mit unterer Rahmenliniefooter- Fußbereich mit oberer Rahmenlinie
Beispiele
<!-- Simple card -->
<UiCard padding="md">
Card content here
</UiCard>
<!-- Card with header and footer -->
<UiCard padding="none">
<template #header>
<div class="px-6 py-4">
<h2>Card Title</h2>
</div>
</template>
<div class="px-6 py-4">
Content here
</div>
<template #footer>
<div class="px-6 py-4 flex justify-end">
<UiButton>Action</UiButton>
</div>
</template>
</UiCard>
<!-- Info callout -->
<UiCard variant="info" padding="md">
<p>This is informational text.</p>
</UiCard>
Modal (UiModal)
Dialog-Overlay mit Hintergrundfläche.
Props
| Prop | Typ | Standard | Beschreibung |
|---|---|---|---|
open | boolean | false | v-model:open |
title | string | - | Titel des Modals |
size | string | 'md' | 'sm', 'md', 'lg', 'xl', '2xl', '3xl', '4xl', 'full' |
closable | boolean | true | Schließen-Button anzeigen |
persistent | boolean | false | Schließen per Klick auf die Hintergrundfläche deaktivieren |
zIndex | number | - | Eigener z-index, um über Elementen mit hohem z-index wie dem E-Mail-Builder zu rendern |
Slots
default- Inhalt des Modalsfooter- Fußbereich des Modals (Buttons)
Events
update:open- Für v-model
Beispiele
<template>
<UiButton @click="showModal = true">Open Modal</UiButton>
<UiModal v-model:open="showModal" title="Confirm Action" size="sm">
<p>Are you sure you want to proceed?</p>
<template #footer>
<UiButton variant="ghost" @click="showModal = false"> Cancel </UiButton>
<UiButton variant="primary" @click="handleConfirm"> Confirm </UiButton>
</template>
</UiModal>
</template>
Modal Footer (UiModalFooter)
Fußbereichs-Komponente für Modals mit Abbrechen- und Bestätigen-Button.
Props
| Prop | Typ | Standard | Beschreibung |
|---|---|---|---|
cancelText | string | 'Cancel' | Beschriftung des Abbrechen-Buttons |
confirmText | string | 'Confirm' | Beschriftung des Bestätigen-Buttons |
confirmVariant | string | 'primary' | Button-Variante: 'primary', 'secondary', 'ghost', 'danger', 'danger-ghost' usw. |
isLoading | boolean | false | Deaktiviert die Buttons und zeigt den Ladezustand |
isDisabled | boolean | false | Deaktiviert den Bestätigen-Button |
Slots
default- Eigener Inhalt des Fußbereichs (überschreibt die Standardbuttons)
Events
cancel- Abbrechen-Button geklicktconfirm- Bestätigen-Button geklickt
Badge (UiBadge)
Statusanzeige mit Varianten.
Props
| Prop | Typ | Standard | Beschreibung |
|---|---|---|---|
variant | string | 'default' | 'default', 'success', 'warning', 'error', 'neutral' |
size | string | 'sm' | 'sm', 'md' |
dot | boolean | false | Punkt statt Hintergrund anzeigen |
Slots
default- Badge-Texticon- Icon vor dem Text
Beispiele
<UiBadge variant="success">Active</UiBadge>
<UiBadge variant="warning">Pending</UiBadge>
<UiBadge variant="error">Failed</UiBadge>
<!-- With dot -->
<UiBadge variant="success" dot>Online</UiBadge>
Tabs (UiTabs)
Tab-Navigation mit Tastaturunterstützung.
Props
| Prop | Typ | Standard | Beschreibung |
|---|---|---|---|
modelValue | string | - | v-model (Wert des aktiven Tabs) |
tabs | array | [{ value, label, count? }] |
Beispiele
<UiTabs
v-model="activeTab"
:tabs="[
{ value: 'all', label: 'All', count: 25 },
{ value: 'active', label: 'Active', count: 20 },
{ value: 'draft', label: 'Drafts', count: 5 },
]"
/>
Toggle (UiToggle)
Umschalter auf Icon-Basis.
Props
| Prop | Typ | Standard | Beschreibung |
|---|---|---|---|
modelValue | boolean | false | v-model-Wert |
label | string | - | Zugängliches Label |
size | string | 'md' | 'sm', 'md' |
disabled | boolean | false | Toggle deaktivieren |
Beispiele
<UiToggle v-model="enabled" label="Enable feature" />
Empty State (UiEmptyState)
Platzhalter für leere Daten.
Props
| Prop | Typ | Standard | Beschreibung |
|---|---|---|---|
icon | string | - | Nuxt-/Lucide-Iconname (z. B. lucide:inbox), gerendert über UiIconBox |
title | string | erforderlich | Hauptüberschrift |
description | string | - | Sekundärtext |
Slots
action- CTA-Button
Beispiele
<UiEmptyState
icon="lucide:mail"
title="No emails yet"
description="Create your first email template to get started."
>
<template #action>
<UiButton variant="primary">
<template #iconLeft>
<Icon name="lucide:plus" class="w-4 h-4" />
</template>
Create Template
</UiButton>
</template>
</UiEmptyState>
Error Boundary (UiErrorBoundary)
Fängt Fehler aus Kindkomponenten ab und zeigt eine Fallback-Oberfläche mit optionaler Wiederholung an.
Props
| Prop | Typ | Standard | Beschreibung |
|---|---|---|---|
fallbackMessage | string | 'Something went wrong. Please try again.' | Eigene Fallback-Meldung |
showRetry | boolean | true | Ob ein Wiederholen-Button angezeigt wird |
Slots
default- Zu rendernder Inhalt (von der Error Boundary abgefangen)
Beispiele
<UiErrorBoundary fallback-message="Failed to load contacts.">
<ContactList />
</UiErrorBoundary>
Error Alert (UiErrorAlert)
Hinweisbanner zur Anzeige von Fehler-, Warn-, Info- oder Erfolgsmeldungen.
Props
| Prop | Typ | Standard | Beschreibung |
|---|---|---|---|
message | string | erforderlich | Text der Meldung |
title | string | - | Eigener Titel (standardmäßig ein variantenabhängiger Titel) |
variant | string | 'error' | 'error', 'warning', 'info', 'success' |
Beispiele
<UiErrorAlert message="Failed to save changes." />
<UiErrorAlert variant="warning" message="Your domain DNS is not yet verified." />
<UiErrorAlert variant="success" message="Campaign sent successfully!" />
Confirmation Dialog (UiConfirmationDialog)
Modal zum Bestätigen bzw. Abbrechen mit anpassbarem Titel, anpassbarer Beschreibung und Variantenstilen.
Props
| Prop | Typ | Standard | Beschreibung |
|---|---|---|---|
open | boolean | - | Steuert die Sichtbarkeit des Dialogs |
title | string | 'Are you sure?' | Titel des Dialogs |
description | string | 'This action cannot be undone.' | Beschreibung des Dialogs |
confirmText | string | 'Confirm' | Text des Bestätigen-Buttons |
cancelText | string | 'Cancel' | Text des Abbrechen-Buttons |
variant | string | 'default' | 'danger', 'warning', 'default' |
isLoading | boolean | false | Zeigt einen Ladespinner auf dem Bestätigen-Button |
persistent | boolean | false | Verhindert das Schließen per Klick auf die Hintergrundfläche |
Slots
default- Eigener Inhalt oberhalb der Aktionsbuttons
Events
update:open- Sichtbarkeit des Dialogs geändertconfirm- Bestätigen-Button geklicktcancel- Abbrechen-Button geklickt
Beispiele
<UiConfirmationDialog
v-model:open="showDeleteDialog"
title="Delete Contact"
description="This will permanently remove the contact and all associated data."
variant="danger"
confirm-text="Delete"
:is-loading="isDeleting"
@confirm="handleDelete"
/>
Dropdown Menu (UiDropdownMenu)
Kontextmenü, das ein Abschneiden durch Overflow vermeidet.
Props
| Prop | Typ | Standard | Beschreibung |
|---|---|---|---|
open | boolean | false | v-model:open |
position | string | 'right' | 'left', 'right' |
Slots
trigger- Button, der das Menü öffnetdefault- Menüeinträge
Verwandte Komponenten
UiDropdownMenuItem- Menüeintrag mit den Props icon, disabled und dangerUiDropdownDivider- Trennlinie
Beispiele
<UiDropdownMenu v-model:open="menuOpen">
<template #trigger>
<button class="btn btn-ghost p-2">
<Icon name="lucide:more-vertical" class="w-4 h-4" />
</button>
</template>
<UiDropdownMenuItem icon="lucide:pencil" @click="handleEdit">
Edit
</UiDropdownMenuItem>
<UiDropdownMenuItem icon="lucide:copy" @click="handleDuplicate">
Duplicate
</UiDropdownMenuItem>
<UiDropdownDivider />
<UiDropdownMenuItem icon="lucide:trash-2" danger @click="handleDelete">
Delete
</UiDropdownMenuItem>
</UiDropdownMenu>
Dropdown Menu Item (UiDropdownMenuItem)
Menüeintrag zur Verwendung innerhalb von UiDropdownMenu.
Props
| Prop | Typ | Standard | Beschreibung |
|---|---|---|---|
icon | string | - | Nuxt-/Lucide-Iconname (z. B. lucide:pencil), gerendert über <Icon :name> |
disabled | boolean | false | Deaktiviert den Menüeintrag |
danger | boolean | false | Wendet die Danger-Formatierung an |
Slots
default- Beschriftung des Menüeintrags
Events
click- Eintrag geklickt
Dropdown Divider (UiDropdownDivider)
Trennlinie zur Verwendung innerhalb von UiDropdownMenu. Keine Props.
Selectable List Item (UiSelectableListItem)
Listeneintrag mit Radio- oder Checkbox-Auswahl.
Props
| Prop | Typ | Standard | Beschreibung |
|---|---|---|---|
label | string | erforderlich | Beschriftungstext des Eintrags |
description | string | - | Optionale Beschreibung |
type | string | 'radio' | 'radio' oder 'checkbox' |
modelValue | string / boolean / string | - | Aktuell ausgewählter Wert |
value | string | - | Wert des Eintrags |
name | string | - | name-Attribut des Inputs |
disabled | boolean | false | Deaktiviert den Eintrag |
Beispiele
<UiSelectableListItem
v-model="selectedPlan"
value="pro"
label="Pro Plan"
description="Up to 10,000 contacts"
name="plan"
/>
Segmented Control (UiSegmentedControl)
Tab-ähnlicher segmentierter Auswahlschalter mit animiertem Indikator.
Props
| Prop | Typ | Standard | Beschreibung |
|---|---|---|---|
options | array | erforderlich | [{ value, label, disabled? }] |
modelValue | string | - | Aktuell ausgewählter Wert |
size | string | 'md' | 'sm', 'md' |
Slots
option-{value}- Eigenes Rendering für eine bestimmte Option (erhält die Propsoptionundactive)
Beispiele
<UiSegmentedControl
v-model="view"
:options="[
{ value: 'grid', label: 'Grid' },
{ value: 'list', label: 'List' },
]"
/>
Stat Card (UiStatCard)
Karte zur Anzeige einer Kennzahl mit Wert, Beschriftung und Variante.
Props
| Prop | Typ | Standard | Beschreibung |
|---|---|---|---|
value | string / number | erforderlich | Wert der Kennzahl |
label | string | erforderlich | Beschriftung der Kennzahl |
variant | string | 'default' | 'default', 'success', 'warning', 'error', 'secondary' |
Beispiele
<UiStatCard value="1,234" label="Total Contacts" />
<UiStatCard value="98.5%" label="Delivery Rate" variant="success" />
<UiStatCard value="12" label="Bounces" variant="error" />
Step Indicator (UiStepIndicator)
Fortschrittsanzeige, die Schritte mit Abschlussstatus und Verbindungslinien darstellt.
Props
| Prop | Typ | Standard | Beschreibung |
|---|---|---|---|
steps | array | erforderlich | [{ id, label, number }] |
getStepStatus | function | erforderlich | (stepId: string) => 'completed' | 'current' | 'upcoming' |
isConnectorHighlighted | function | erforderlich | (index: number) => boolean — bestimmt die Hervorhebung der Verbindungslinie |
Beispiele
<UiStepIndicator
:steps="[
{ id: 'domain', label: 'Add Domain', number: 1 },
{ id: 'dns', label: 'Configure DNS', number: 2 },
{ id: 'verify', label: 'Verify', number: 3 },
]"
:get-step-status="getStatus"
:is-connector-highlighted="(i) => i < currentStep"
/>
Toast (useToast)
Globale Toast-Benachrichtigungen über ein Composable.
Verwendung
const { showToast } = useToast();
// Success (default)
showToast('Saved successfully');
// Error
showToast('Failed to save', 'error');
Toasts blenden sich nach 3 Sekunden automatisch aus. Mehrere Toasts stapeln sich vertikal.
Icon Box (UiIconBox)
Ein abgerundeter Container, der ein einzelnes Icon aufnimmt — verwendet für Empty States, Listenzeilen und Abschnittsüberschriften. Rendert das Icon über Nuxts <Icon>.
Props
| Prop | Typ | Standard | Beschreibung |
|---|---|---|---|
icon | string | erforderlich | Nuxt-/Lucide-Iconname (z. B. lucide:users) |
size | string | 'md' | 'xs', 'sm', 'md', 'lg', 'xl' |
variant | string | 'brand' | 'brand', 'success', 'warning', 'error', 'surface', 'inverse' |
rounded | string | 'xl' | 'lg', 'xl', '2xl', 'full' |
Beispiele
<UiIconBox icon="lucide:users" />
<UiIconBox icon="lucide:check" variant="success" size="sm" rounded="full" />
<UiIconBox icon="lucide:inbox" size="xl" variant="surface" rounded="2xl" />
Einrichtung
UiToast wird einmalig in apps/web/app/app.vue eingebunden, um global verfügbar zu sein. Es ist in <ClientOnly> verpackt, um eine SSR-Hydration-Diskrepanz zu vermeiden:
<template>
<div>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
<!-- Global toast notifications (client-only to avoid SSR hydration mismatch) -->
<ClientOnly>
<UiToast />
</ClientOnly>
</div>
</template>
Theme Toggle (UiThemeToggle)
Ein einzelner Button, der das Farbschema durch System -> Hell -> Dunkel schaltet. Intern verwendet er @nuxtjs/color-mode und speichert die Einstellung automatisch. Das Icon (Monitor / Sonne / Mond) spiegelt den aktuellen Modus wider. Es gibt keine Props; ein optionaler Default-Slot erlaubt es, eine Textbeschriftung neben dem Icon anzufügen.
Beispiele
<!-- Icon-only toggle -->
<UiThemeToggle class="p-2 rounded-lg hover:bg-bg-surface" />
<!-- With a label -->
<UiThemeToggle class="flex items-center gap-2">
Theme
</UiThemeToggle>
Chart-Kit
Handgeschriebene SVG-Diagramme auf Basis von Design-Tokens — ohne Diagrammbibliothek. Vier Komponenten teilen sich dieselben Regeln:
- Nur eine Achse. Niemals zwei Skalen; brauchen zwei Reihen unterschiedliche Skalen, verwenden Sie zwei Diagramme.
- Eine einzelne Reihe = Markenfarbton (
--color-brand, der Standardwert voncolorbei jeder Komponente). - Mehrere Reihen/kategorial = die Palette in fester Reihenfolge
--chart-cat-1…--chart-cat-4(in beiden Themes auf Farbfehlsichtigkeit und Kontrast geprüft). Weisen Sie die Farben der Reihe nach zu — mischen Sie sie niemals, damit es „hübsch aussieht“. - Text in Text-Tokens, niemals in Reihenfarben. Beschriftungen und Werte verwenden
text-text-*/fill-text-tertiary; Farbe gehört ausschließlich den Marks. - Zurückhaltende Raster. Rasterlinien verwenden
--chart-grid, gestrichelt, Strichstärke 0,5; die Grundlinie ist durchgezogen. - Tabellenziffern überall dort, wo eine Zahl ihre Breite ändern kann.
Trend Chart (UiTrendChart)
Linien-/Flächen-Zeitreihe mit zurückhaltendem gestricheltem Raster, y-Achsen-Beschriftungen für Max/Mitte/Min, x-Beschriftungen für den ersten und letzten Wert, einem Endpunkt-Punkt sowie einem Fadenkreuz beim Hovern samt Tooltip.
Props
| Prop | Typ | Standard | Beschreibung |
|---|---|---|---|
data | { label, value }[] | erforderlich | Geordnete Reihe (Beschriftungen sind kategorial) |
color | string | var(--color-brand) | Farbe von Linie und Markern |
showArea | boolean | true | Füllung unter der Linie mit 10 % Deckkraft |
formatValue | (value: number) => string | kompakt (1.2k) | Zahlenformat für Achse und Tooltip |
ariaLabel | string | 'Trend chart' | Zugänglicher Name für das SVG |
Beispiele
<UiTrendChart
:data="days.map((d) => ({ label: d.label, value: d.opens }))"
aria-label="Opens per day over the last 30 days"
/>
<!-- Second categorical series on its own chart, palette order preserved -->
<UiTrendChart :data="clicksSeries" color="var(--chart-cat-2)" :show-area="false" />
Sparkline (UiSparkline)
Eingebettete Mini-Polylinie (keine Achsen, kein Raster) mit einem Endpunkt-Punkt, für Listenzeilen und Kennzahlenkacheln. ariaLabel ist erforderlich — die Sparkline selbst ist rein visuell.
Props
| Prop | Typ | Standard | Beschreibung |
|---|---|---|---|
data | number | erforderlich | Geordnete Werte |
ariaLabel | string | erforderlich | Zugängliche Zusammenfassung des Trends |
color | string | var(--color-brand) | Linienfarbe |
width | number | 88 | Breite in px |
height | number | 26 | Höhe in px |
Beispiele
<UiSparkline :data="weeklyOpens" aria-label="Opens trending up over the last 8 weeks" />
Stat Tile (UiStatTile)
Die Kennzahl des Chart-Kits: gedämpfte Beschriftung in Großbuchstaben, Display-Ziffer in Instrument Serif (tabular-nums), optionale Delta-Zeile. Verwenden Sie sie, wenn die Zahl der Held einer Diagrammfläche ist; für schlichte farbige Kennzahlenwerte behalten Sie UiStatCard.
Props
| Prop | Typ | Standard | Beschreibung |
|---|---|---|---|
label | string | erforderlich | Beschriftung der Kachel in Großbuchstaben |
value | string / number | erforderlich | Anzeigewert (vorformatiert) |
delta | string | - | Delta-Text, z. B. '12% vs last week' |
deltaDirection | 'up' / 'down' / 'flat' | 'flat' | up = success, down = error, flat = tertiary |
Beispiele
<UiStatTile label="Delivered" value="12,480" delta="8% vs last week" delta-direction="up" />
<UiStatTile label="Bounces" :value="bounces" delta="2 more than usual" delta-direction="down" />
Bars (UiBars)
Schmale vertikale Balken, an der Grundlinie verankert: abgerundete Datenenden, 2 px Abstand, Tooltip pro Balken beim Hovern und bei Tastaturfokus (nur über Deckkraft — kein Layout-Sprung), optionale spärliche x-Beschriftungen. Nullwerte werden als 2 px hoher Grundlinien-Stummel in --chart-grid gerendert.
Props
| Prop | Typ | Standard | Beschreibung |
|---|---|---|---|
data | { label, value }[] | erforderlich | Geordnete Balken |
color | string | var(--color-brand) | Balkenfüllung |
height | number | 128 | Höhe der Plotfläche in px (Beschriftungen kommen darunter hinzu) |
labelEvery | number | 0 | Jede N-te x-Beschriftung anzeigen (die letzte immer); 0 = keine |
formatValue | (value: number) => string | toLocaleString() | Wertformat für Tooltip und aria |
ariaLabel | string | 'Bar chart' | Zugänglicher Name für die Diagrammgruppe |
Beispiele
<UiBars
:data="sendVolume.map((d) => ({ label: d.label, value: d.count }))"
:label-every="1"
:format-value="(v) => `${v.toLocaleString()} emails`"
aria-label="Emails sent per day over the last 7 days"
/>
Helfer
Die reinen Geometrie- und Formatierungshelfer hinter dem Kit liegen in packages/ui/utils/chart.ts (computeChartPoints, computeYBounds, buildAreaPath, formatChartValue, …) und sind unit-getestet; verwenden Sie sie für maßgeschneiderte SVG-Diagramme wieder, statt Skalen erneut herzuleiten.
Mikrointeraktions-Kit
Wiederverwendbare Motion-Drop-ins im Sinne des Fluid Functionalism, definiert in packages/ui/assets/css/motion.css und über das Design-System-Barrel importiert — in jeder App ohne zusätzliche Einrichtung verfügbar. Sie alle nutzen die gemeinsamen Motion-Tokens (--motion-fast/--motion-moderate, --ease-spring) — niemals handgeschriebene Millisekundenwerte — und reduzieren sich unter prefers-reduced-motion auf reine Deckkraftänderungen (oder auf gar nichts).
Hover-Reveal (.ui-hover-reveal)
Einblenden eines Aktions-Clusters allein über die Deckkraft, sobald seine Zeile gehovert oder fokussiert wird. Das Cluster bleibt in voller Größe im DOM (Deckkraft, nicht display), sodass das Einblenden nie das Layout verschiebt, und pointer-events werden zusammen mit der Einblendung geschaltet, damit unsichtbare Aktionen auf Touch-Geräten nie antippbar sind. Auslösen über Tailwinds group-Klasse oder ein explizites .ui-hover-reveal-host an der Zeile; auch Tastaturfokus innerhalb der Zeile (:focus-within) blendet es ein.
<!-- DO: cluster inside a hovered/focused host; absolute so it overlays -->
<li class="group relative">
<span>{{ item.title }}</span>
<div class="ui-hover-reveal absolute right-3 top-1/2 -translate-y-1/2 flex gap-0.5">
<button type="button" aria-label="Archive">…</button>
</div>
</li>
<!-- DON'T: v-if / display toggles shift layout and drop keyboard access -->
<li @mouseenter="show = true" @mouseleave="show = false">
<div v-if="show">…</div>
</li>
Spring-Press (.ui-press)
Ein Druckeffekt mit scale: 0.98 bei :active, getragen von --motion-fast + --ease-spring. Für maßgeschneiderte interaktive Elemente (Icon-Buttons, Karten, die als Buttons fungieren) — .btn bringt seinen eigenen Druckeffekt bereits mit.
<!-- DO -->
<button type="button" class="ui-press p-2 rounded-lg hover:bg-bg-surface">…</button>
<!-- DON'T: hand-rolled press with hardcoded timing, or doubling up on .btn
(which already presses) -->
<button class="btn btn-primary ui-press">…</button>
<button class="active:scale-95 transition-transform duration-100">…</button>
Gestaffelter Auftritt (.ui-stagger)
An einen Listencontainer setzen: direkte Kinder treten mit Deckkraft und einem Anstieg von 6 px in Schritten von 20 ms auf der mittleren Stufe ein. Gedacht für kurze Listen (bis zu 8 Einträge — Warteschlangen, Aktionsdecks, Dashboards); spätere Einträge teilen sich die letzte Verzögerung, damit lange Listen nie träge wirken. Bei reduzierter Bewegung erscheinen die Einträge einfach.
<!-- DO: a short, meaningful queue -->
<ul class="ui-stagger">
<li v-for="task in todaysTasks" :key="task.id">…</li>
</ul>
<!-- DON'T: hundreds of virtualized rows — the animation replays on every
scroll-in and delays reading the data -->
<ul class="ui-stagger"><li v-for="msg in allMessages" :key="msg.id">…</li></ul>
Nähe-Betonung (.ui-proximity)
Für dichte Icon-Zeilen (Toolbars, Schnellaktions-Cluster): Das gehoverte Ziel hebt sich leicht ab, seine unmittelbaren Nachbarn bleiben nahezu voll deckend, der Rest tritt zurück — der Fokus folgt dem Zeiger, rein per CSS. Tastaturfokus (:focus-visible) erhält dieselbe Betonung.
<!-- DO: a dense, single-purpose icon row -->
<div class="ui-proximity flex items-center gap-1">
<button type="button" aria-label="Reply">…</button>
<button type="button" aria-label="Archive">…</button>
<button type="button" aria-label="Snooze">…</button>
</div>
<!-- DON'T: on mixed content — receding siblings reads as disabling them -->
<nav class="ui-proximity">…text links and headings…</nav>
Zahlen-Ticker (UiNumberTicker)
Animierte Ziffer für Kennzahlenkacheln und Zähler: Ändert sich value, rollt die angezeigte Zahl über einen --motion-moderate-Takt zum neuen Wert. Immer tabular-nums, damit Ziffern horizontal nie springen. Unter prefers-reduced-motion wird schlichter Text gerendert, der sich einfach aktualisiert.
Props
| Prop | Typ | Standard | Beschreibung |
|---|---|---|---|
value | number | erforderlich | Zielwert; Änderungen werden animiert |
formatter | (value: number) => string | gerundet + gruppiert | Anzeigeformat für den laufenden Wert |
Beispiele
<!-- DO: hero numeral that updates live -->
<p class="text-2xl font-semibold"><UiNumberTicker :value="stats.sentToday" /></p>
<!-- Custom format -->
<UiNumberTicker :value="deliveryRate" :formatter="(n) => `${(n * 100).toFixed(1)}%`" />
<!-- DON'T: static values that never change (plain text is simpler), or
inside sentences where rolling digits distract from reading -->
<p>You have <UiNumberTicker :value="3" /> drafts.</p>