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

PropTypStandardBeschreibung
variantstring'primary''primary', 'secondary', 'outline', 'ghost', 'danger', 'danger-ghost', 'danger-outline'
sizestring'md''sm', 'md', 'lg'
loadingbooleanfalseSpinner anzeigen und Button deaktivieren
disabledbooleanfalseButton deaktivieren
fullWidthbooleanfalseButton über die volle Breite

Slots

  • default - Buttontext
  • iconLeft - Icon vor dem Text
  • iconRight - 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

PropTypStandardBeschreibung
typestring'text''text', 'email', 'password', 'number', 'date'
modelValuestring/number-v-model-Wert
labelstring-Label-Text
placeholderstring-Platzhaltertext
errorstring-Fehlermeldung
helpTextstring-Hilfetext (wird angezeigt, wenn kein Fehler vorliegt)
requiredbooleanfalseSternchen für Pflichtfeld anzeigen
disabledbooleanfalseEingabefeld deaktivieren
sizestring'md''sm', 'md'

Slots

  • iconLeft - Icon auf der linken Seite des Eingabefelds
  • iconRight - 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

PropTypStandardBeschreibung
optionsarray[{ value, label }]
modelValueT | nullnullv-model-Wert (String oder Zahl)
labelstring-Label-Text
placeholderstring'Select an option'Text, der angezeigt wird, wenn keine Option ausgewählt ist
errorstring-Fehlermeldung
requiredbooleanfalseSternchen für Pflichtfeld anzeigen
disabledbooleanfalseSelect deaktivieren
sizestring'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

PropTypStandardBeschreibung
modelValuestring-v-model-Wert
labelstring-Label-Text
placeholderstring-Platzhaltertext
rowsnumber4Anzahl der Zeilen
maxLengthnumber-Maximale Zeichenzahl (zeigt einen Zähler)
resizestring'none''none', 'vertical', 'both'
errorstring-Fehlermeldung
requiredbooleanfalseSternchen 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

PropTypStandardBeschreibung
modelValuebooleanfalsev-model-Wert
labelstring-Label-Text
descriptionstring-Hilfetext unter dem Label
disabledbooleanfalseCheckbox 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

PropTypStandardBeschreibung
modelValuebooleanfalsev-model-Wert
disabledbooleanfalseDen Switch deaktivieren
labelstring-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

PropTypStandardBeschreibung
valuenumber00–100. Wird ignoriert, wenn indeterminate true ist.
variantstring'brand''brand', 'success', 'warning', 'error'
indeterminatebooleanfalseAnimierter Durchlauf für Arbeit unbekannter Dauer
sizestring'md''sm', 'md' (Höhe der Schiene)
ariaLabelstring-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

PropTypStandardBeschreibung
paddingstring'md''none', 'sm', 'md', 'lg'
variantstring'default''default', 'info', 'warning', 'error'
hoverablebooleanfalseRahmeneffekt beim Hovern hinzufügen
clickablebooleanfalseZeiger anzeigen und Click-Event emittieren
overflowstring'visible''visible', 'hidden'

Slots

  • default - Hauptinhalt
  • header - Kopfbereich mit unterer Rahmenlinie
  • footer - 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>

Dialog-Overlay mit Hintergrundfläche.

Props

PropTypStandardBeschreibung
openbooleanfalsev-model:open
titlestring-Titel des Modals
sizestring'md''sm', 'md', 'lg', 'xl', '2xl', '3xl', '4xl', 'full'
closablebooleantrueSchließen-Button anzeigen
persistentbooleanfalseSchließen per Klick auf die Hintergrundfläche deaktivieren
zIndexnumber-Eigener z-index, um über Elementen mit hohem z-index wie dem E-Mail-Builder zu rendern

Slots

  • default - Inhalt des Modals
  • footer - 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>

Fußbereichs-Komponente für Modals mit Abbrechen- und Bestätigen-Button.

Props

PropTypStandardBeschreibung
cancelTextstring'Cancel'Beschriftung des Abbrechen-Buttons
confirmTextstring'Confirm'Beschriftung des Bestätigen-Buttons
confirmVariantstring'primary'Button-Variante: 'primary', 'secondary', 'ghost', 'danger', 'danger-ghost' usw.
isLoadingbooleanfalseDeaktiviert die Buttons und zeigt den Ladezustand
isDisabledbooleanfalseDeaktiviert den Bestätigen-Button

Slots

  • default - Eigener Inhalt des Fußbereichs (überschreibt die Standardbuttons)

Events

  • cancel - Abbrechen-Button geklickt
  • confirm - Bestätigen-Button geklickt

Badge (UiBadge)

Statusanzeige mit Varianten.

Props

PropTypStandardBeschreibung
variantstring'default''default', 'success', 'warning', 'error', 'neutral'
sizestring'sm''sm', 'md'
dotbooleanfalsePunkt statt Hintergrund anzeigen

Slots

  • default - Badge-Text
  • icon - 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

PropTypStandardBeschreibung
modelValuestring-v-model (Wert des aktiven Tabs)
tabsarray[{ 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

PropTypStandardBeschreibung
modelValuebooleanfalsev-model-Wert
labelstring-Zugängliches Label
sizestring'md''sm', 'md'
disabledbooleanfalseToggle deaktivieren

Beispiele

<UiToggle v-model="enabled" label="Enable feature" />

Empty State (UiEmptyState)

Platzhalter für leere Daten.

Props

PropTypStandardBeschreibung
iconstring-Nuxt-/Lucide-Iconname (z. B. lucide:inbox), gerendert über UiIconBox
titlestringerforderlichHauptüberschrift
descriptionstring-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

PropTypStandardBeschreibung
fallbackMessagestring'Something went wrong. Please try again.'Eigene Fallback-Meldung
showRetrybooleantrueOb 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

PropTypStandardBeschreibung
messagestringerforderlichText der Meldung
titlestring-Eigener Titel (standardmäßig ein variantenabhängiger Titel)
variantstring'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

PropTypStandardBeschreibung
openboolean-Steuert die Sichtbarkeit des Dialogs
titlestring'Are you sure?'Titel des Dialogs
descriptionstring'This action cannot be undone.'Beschreibung des Dialogs
confirmTextstring'Confirm'Text des Bestätigen-Buttons
cancelTextstring'Cancel'Text des Abbrechen-Buttons
variantstring'default''danger', 'warning', 'default'
isLoadingbooleanfalseZeigt einen Ladespinner auf dem Bestätigen-Button
persistentbooleanfalseVerhindert das Schließen per Klick auf die Hintergrundfläche

Slots

  • default - Eigener Inhalt oberhalb der Aktionsbuttons

Events

  • update:open - Sichtbarkeit des Dialogs geändert
  • confirm - Bestätigen-Button geklickt
  • cancel - 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"
/>

Kontextmenü, das ein Abschneiden durch Overflow vermeidet.

Props

PropTypStandardBeschreibung
openbooleanfalsev-model:open
positionstring'right''left', 'right'

Slots

  • trigger - Button, der das Menü öffnet
  • default - Menüeinträge

Verwandte Komponenten

  • UiDropdownMenuItem - Menüeintrag mit den Props icon, disabled und danger
  • UiDropdownDivider - 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>

Menüeintrag zur Verwendung innerhalb von UiDropdownMenu.

Props

PropTypStandardBeschreibung
iconstring-Nuxt-/Lucide-Iconname (z. B. lucide:pencil), gerendert über <Icon :name>
disabledbooleanfalseDeaktiviert den Menüeintrag
dangerbooleanfalseWendet die Danger-Formatierung an

Slots

  • default - Beschriftung des Menüeintrags

Events

  • click - Eintrag geklickt

Trennlinie zur Verwendung innerhalb von UiDropdownMenu. Keine Props.

Selectable List Item (UiSelectableListItem)

Listeneintrag mit Radio- oder Checkbox-Auswahl.

Props

PropTypStandardBeschreibung
labelstringerforderlichBeschriftungstext des Eintrags
descriptionstring-Optionale Beschreibung
typestring'radio''radio' oder 'checkbox'
modelValuestring / boolean / string-Aktuell ausgewählter Wert
valuestring-Wert des Eintrags
namestring-name-Attribut des Inputs
disabledbooleanfalseDeaktiviert 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

PropTypStandardBeschreibung
optionsarrayerforderlich[{ value, label, disabled? }]
modelValuestring-Aktuell ausgewählter Wert
sizestring'md''sm', 'md'

Slots

  • option-{value} - Eigenes Rendering für eine bestimmte Option (erhält die Props option und active)

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

PropTypStandardBeschreibung
valuestring / numbererforderlichWert der Kennzahl
labelstringerforderlichBeschriftung der Kennzahl
variantstring'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

PropTypStandardBeschreibung
stepsarrayerforderlich[{ id, label, number }]
getStepStatusfunctionerforderlich(stepId: string) => 'completed' | 'current' | 'upcoming'
isConnectorHighlightedfunctionerforderlich(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

PropTypStandardBeschreibung
iconstringerforderlichNuxt-/Lucide-Iconname (z. B. lucide:users)
sizestring'md''xs', 'sm', 'md', 'lg', 'xl'
variantstring'brand''brand', 'success', 'warning', 'error', 'surface', 'inverse'
roundedstring'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 von color bei 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

PropTypStandardBeschreibung
data{ label, value }[]erforderlichGeordnete Reihe (Beschriftungen sind kategorial)
colorstringvar(--color-brand)Farbe von Linie und Markern
showAreabooleantrueFüllung unter der Linie mit 10 % Deckkraft
formatValue(value: number) => stringkompakt (1.2k)Zahlenformat für Achse und Tooltip
ariaLabelstring'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

PropTypStandardBeschreibung
datanumbererforderlichGeordnete Werte
ariaLabelstringerforderlichZugängliche Zusammenfassung des Trends
colorstringvar(--color-brand)Linienfarbe
widthnumber88Breite in px
heightnumber26Hö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

PropTypStandardBeschreibung
labelstringerforderlichBeschriftung der Kachel in Großbuchstaben
valuestring / numbererforderlichAnzeigewert (vorformatiert)
deltastring-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

PropTypStandardBeschreibung
data{ label, value }[]erforderlichGeordnete Balken
colorstringvar(--color-brand)Balkenfüllung
heightnumber128Höhe der Plotfläche in px (Beschriftungen kommen darunter hinzu)
labelEverynumber0Jede N-te x-Beschriftung anzeigen (die letzte immer); 0 = keine
formatValue(value: number) => stringtoLocaleString()Wertformat für Tooltip und aria
ariaLabelstring'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

PropTypStandardBeschreibung
valuenumbererforderlichZielwert; Änderungen werden animiert
formatter(value: number) => stringgerundet + gruppiertAnzeigeformat 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>