docs/ai/context/ui-components.md
@proj-airi/ui Component ReferenceAuto-maintained: When adding or updating components in
packages/ui, update this document accordingly.
Standardized primitives built on reka-ui. Minimal business logic — use these instead of raw DOM elements.
Source: packages/ui/src/components/
Bidirectional Vue <Transition> wrapper with customizable CSS classes.
| Prop | Type | Default | Description |
|---|---|---|---|
fromClass | string? | — | CSS class for initial state |
activeClass | string? | — | CSS class during transition |
toClass | string? | — | CSS class for final state |
Slots: default
Horizontal slide/fade transition (0.5s hardcoded).
Props: None | Slots: default
Smooth vertical expand/collapse with height animation and opacity control.
| Prop | Type | Default | Description |
|---|---|---|---|
duration | number? | 250 | Animation duration (ms) |
easingEnter | string? | 'ease-in-out' | Enter easing function |
easingLeave | string? | 'ease-in-out' | Leave easing function |
opacityClosed | number? | 0 | Opacity when closed |
opacityOpened | number? | 1 | Opacity when opened |
Slots: default
Expandable/collapsible container with trigger button and vertical animation.
| Prop | Type | Default | Description |
|---|---|---|---|
default | boolean? | — | Initial visibility |
label | string? | — | Trigger button label |
v-model: visible: boolean
Slots: trigger({ visible, setVisible }), default({ visible, setVisible })
Responsive screen component that calculates canvas dimensions based on breakpoints.
Props: None | Slots: default({ width, height })
Loading placeholder with animation.
| Prop | Type | Default | Description |
|---|---|---|---|
animation | 'pulse' | 'wave' | 'none' | 'pulse' | Animation style |
Slots: default
Line-clamped content container that expands and collapses when the overflowing content area is clicked.
| Prop | Type | Default | Description |
|---|---|---|---|
lineClamp | number? | 3 | Maximum visible lines while collapsed |
Slots: default
Versatile button with variants, sizes, and states.
| Prop | Type | Default | Description |
|---|---|---|---|
toggled | boolean? | false | Toggle state |
icon | string? | — | UnoCSS/Iconify icon class |
label | string? | — | Button text |
disabled | boolean? | false | Disabled state |
loading | boolean? | false | Loading state |
variant | 'primary' | 'secondary' | 'secondary-muted' | 'danger' | 'caution' | 'pure' | 'ghost' | 'primary' | Visual variant |
size | 'sm' | 'md' | 'lg' | 'md' | Size |
shape | 'rounded' | 'pill' | 'square' | 'pill' | Shape |
block | boolean? | false | Full width |
Slots: default (fallback when no label)
Alert/callout box with themed accent bar.
| Prop | Type | Default | Description |
|---|---|---|---|
theme | 'primary' | 'violet' | 'lime' | 'orange' | 'primary' | Color theme |
label | string? | — | Title |
Slots: label, default
Error display with copy/feedback buttons and scrollable stack trace.
| Prop | Type | Default | Description |
|---|---|---|---|
error | unknown? | — | Error object |
message | string? | — | Custom message |
stack | string? | — | Stack trace |
includeStack | boolean? | true | Show stack |
showCopyButton | boolean? | true | Show copy button |
showFeedbackButton | boolean? | true | Show feedback button |
copyButtonLabel | string? | 'Copy' | Copy button text |
copiedButtonLabel | string? | 'Copied' | Copied state text |
feedbackButtonLabel | string? | 'Feedback' | Feedback button text |
heightPreset | 'sm' | 'md' | 'lg' | 'xl' | 'auto' | 'md' | Container height |
Emits: copy(content: string), feedback()
Catches synchronous render/setup errors in descendants via onErrorCaptured and renders a fallback (built-in ContainerError + retry button) instead of letting the error propagate. Use to wrap <RouterView> or any subtree where partial failure should not blank the host layout. Async/unhandled rejections are NOT captured — use app.config.errorHandler for those.
| Prop | Type | Default | Description |
|---|---|---|---|
title | string? | — | Optional title shown above error details |
retryable | boolean? | true | Show built-in retry button |
retryLabel | string? | 'Try again' | Retry button label |
Slots: default, fallback({ error, info, retry })
Emits: error(err, instance, info), retry()
Exposed: retry(), hasError()
Two-stage confirmation button — click once to reveal confirm/cancel.
| Prop | Type | Default | Description |
|---|---|---|---|
variant | ButtonVariant | 'danger' | Confirm button variant |
cancelVariant | ButtonVariant | 'secondary' | Cancel button variant |
size | 'sm' | 'md' | 'lg' | 'md' | Size |
block | boolean? | false | Full width |
disabled | boolean? | false | Disabled |
loading | boolean? | false | Loading |
Emits: confirm(), cancel()
Slots: default (initial text), confirm (confirm text), cancel (cancel text)
Linear progress bar with animated shine.
| Prop | Type | Default | Description |
|---|---|---|---|
progress | number | (required) | Percentage 0–100 |
barClass | string? | — | Custom bar color class |
Basic text/number input.
| Prop | Type | Default | Description |
|---|---|---|---|
type | InputType? | — | HTML input type |
variant | 'primary' | 'secondary' | 'primary-dimmed' | 'primary' | Visual variant |
size | 'sm' | 'md' | 'lg' | 'md' | Size |
v-model: modelValue: string | number
Low-level file input with drag-drop support.
| Prop | Type | Default | Description |
|---|---|---|---|
accept | string? | — | Accepted MIME types |
multiple | boolean? | — | Allow multiple files |
isDraggingClasses | string | string[]? | — | Classes when dragging |
isNotDraggingClasses | string | string[]? | — | Classes when not dragging |
v-model: modelValue: File[]
Slots: default({ isDragging, firstFile, files })
File input with preview and drag-drop UI.
| Prop | Type | Default | Description |
|---|---|---|---|
accept | string? | — | Accepted file types |
multiple | boolean? | — | Allow multiple |
placeholder | string? | 'Choose file' | Placeholder text |
v-model: modelValue: File[] | undefined
Styled file upload card with drag-and-drop zone.
| Prop | Type | Default | Description |
|---|---|---|---|
accept | string? | — | Accepted file types |
multiple | boolean? | — | Allow multiple |
v-model: inherits from BasicInputFile
Slots: default (custom upload UI)
Two-column input for key-value pairs.
| Prop | Type | Default | Description |
|---|---|---|---|
name | string? | — | Input name attribute |
keyPlaceholder | string? | — | Key placeholder |
valuePlaceholder | string? | — | Value placeholder |
v-model: propertyKey: string, propertyValue: string
Auto-resizing textarea with submit and paste-file events.
| Prop | Type | Default | Description |
|---|---|---|---|
defaultHeight | string? | — | Initial height when empty |
submitOnEnter | boolean? | true | Submit on Enter (Shift+Enter for newline) |
v-model: input: string
Emits: submit(message: string), pasteFile(files: File[])
Styled textarea wrapping BasicTextarea.
v-model: modelValue: string
Toggle switch using reka-ui SwitchRoot.
| Prop | Type | Default | Description |
|---|---|---|---|
disabled | boolean? | — | Disabled state |
v-model: modelValue: boolean
Single radio button for radio groups.
| Prop | Type | Default | Description |
|---|---|---|---|
id | string | (required) | Unique ID |
name | string | (required) | Radio group name |
value | string | (required) | Option value |
title | string | (required) | Display label |
deprecated | boolean? | false | Deprecation indicator |
v-model: modelValue: string
Horizontal slider with progress visualization.
| Prop | Type | Default | Description |
|---|---|---|---|
min | number? | 0 | Minimum value |
max | number? | 100 | Maximum value |
step | number? | 1 | Step increment |
disabled | boolean? | false | Disabled |
thumbColor | string? | '#9090906e' | Thumb color |
trackColor | string? | 'gray' | Track color |
trackValueColor | string? | 'red' | Filled track color |
v-model: modelValue: number
HSL hue selector (0–360) with rainbow gradient.
| Prop | Type | Default | Description |
|---|---|---|---|
disabled | boolean? | — | Disabled |
v-model: modelValue: number
Rounded-style slider.
| Prop | Type | Default | Description |
|---|---|---|---|
min | number? | 0 | Minimum |
max | number? | 100 | Maximum |
step | number? | 1 | Step |
disabled | boolean? | false | Disabled |
v-model: modelValue: number
Dropdown select using reka-ui with grouping and custom rendering.
| Prop | Type | Default | Description |
|---|---|---|---|
options | SelectOptionItem<T>[] | SelectOptionGroupItem<T>[] | (required) | Options |
placeholder | string? | 'Select an option' | Placeholder |
disabled | boolean? | false | Disabled |
by | string | ((a: T, b: T) => boolean)? | — | Custom comparison |
contentMinWidth | string | number? | 160 | Dropdown min width |
contentWidth | string | number? | — | Dropdown width |
shape | 'rounded' | 'default' | 'default' | Shape |
variant | 'blurry' | 'default' | 'default' | Variant |
v-model: modelValue: T
Slots: value({ option, value, placeholder }), option({ option })
Individual option item within Select.
| Prop | Type | Default | Description |
|---|---|---|---|
option | SelectOptionItem<T> | (required) | Option data |
Slots: default
Searchable dropdown/autocomplete using reka-ui with grouping.
| Prop | Type | Default | Description |
|---|---|---|---|
options | ComboboxOptionItem<T>[] | ComboboxOptionGroupItem<T>[] | (required) | Options |
placeholder | string? | — | Placeholder |
disabled | boolean? | false | Disabled |
contentMinWidth | string | number? | — | Dropdown min width |
contentWidth | string | number? | — | Dropdown width |
v-model: modelValue: T
Slots: option({ option }), empty
Simplified Combobox wrapper for string/number options.
| Prop | Type | Default | Description |
|---|---|---|---|
options | { label, value, description?, disabled?, icon? }[]? | — | Options |
placeholder | string? | — | Placeholder |
disabled | boolean? | false | Disabled |
title | string? | — | Title |
layout | 'horizontal' | 'vertical'? | — | Layout direction |
contentMinWidth | string | number? | — | Dropdown min width |
contentWidth | string | number? | — | Dropdown width |
v-model: modelValue: string | number
Slots: option({ option }), empty
Option item within combobox (uses provide/inject).
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | number | (required) | Value |
label | string? | — | Display text |
active | boolean? | — | Active state |
Slots: default
Tab-like selection using radio buttons with animated indicator.
| Prop | Type | Default | Description |
|---|---|---|---|
options | SelectTabOption[] | (required) | Tab options { label, value, description?, icon? } |
disabled | boolean? | false | Disabled |
readonly | boolean? | false | Read-only |
size | 'sm' | 'md' | 'md' | Size |
v-model: modelValue: T
All Field components wrap a base input with label, description, and consistent layout. Common slots: label, description.
| Prop | Type | Default | Description |
|---|---|---|---|
label | string? | — | Label |
description | string? | — | Helper text |
placeholder | string? | — | Placeholder |
required | boolean? | — | Required indicator |
type | InputType? | — | Input type |
inputClass | string? | — | Custom input class |
singleLine | boolean? | true | true = input, false = textarea |
v-model: modelValue: T
| Prop | Type | Default | Description |
|---|---|---|---|
label | string? | — | Label |
description | string? | — | Helper text |
disabled | boolean? | — | Disabled |
placement | 'left' | 'right' | 'right' | Switch position |
v-model: modelValue: boolean
| Prop | Type | Default | Description |
|---|---|---|---|
label | string? | — | Label |
description | string? | — | Helper text |
placeholder | string? | — | Placeholder |
required | boolean? | — | Required indicator |
textareaClass | string? | — | Custom textarea class |
rows | number? | 6 | Rows |
v-model: modelValue: string
| Prop | Type | Default | Description |
|---|---|---|---|
min | number? | — | Min |
max | number? | — | Max |
step | number? | — | Step |
label | string? | — | Label |
description | string? | — | Helper text |
formatValue | (value: number) => string? | — | Value formatter |
as | 'label' | 'div' | 'label' | Wrapper element |
v-model: modelValue: number
| Prop | Type | Default | Description |
|---|---|---|---|
label | string? | — | Label |
description | string? | — | Helper text |
accept | string? | — | Accepted types |
multiple | boolean? | — | Multiple |
placeholder | string? | — | Placeholder |
v-model: modelValue: File[] | undefined
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | (required) | Label |
description | string? | — | Helper text |
options | SelectOptionItem<T>[] | SelectOptionGroupItem<T>[]? | — | Options |
placeholder | string? | — | Placeholder |
disabled | boolean? | — | Disabled |
layout | 'horizontal' | 'vertical' | 'horizontal' | Layout |
by | string | ((a, b) => boolean)? | — | Comparison |
shape | 'rounded' | 'default'? | — | Shape |
variant | 'blurry' | 'default'? | — | Variant |
v-model: modelValue: T
Slots: label, description, value, option
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | (required) | Label |
description | string? | — | Helper text |
options | { label, value, description?, disabled?, icon? }[]? | — | Options |
placeholder | string? | — | Placeholder |
disabled | boolean? | false | Disabled |
layout | 'horizontal' | 'vertical' | 'horizontal' | Layout |
v-model: modelValue: string
Slots: label, description, option, empty
Dynamic key-value pair list with add/remove.
| Prop | Type | Default | Description |
|---|---|---|---|
label | string? | — | Label |
description | string? | — | Helper text |
name | string? | — | Input name |
keyPlaceholder | string? | — | Key placeholder |
valuePlaceholder | string? | — | Value placeholder |
required | boolean? | — | Required |
inputClass | string? | — | Custom input class |
v-model: keyValues: { key: string, value: string }[]
Emits: remove(index: number), add(key: string, value: string)
Dynamic string list with add/remove.
| Prop | Type | Default | Description |
|---|---|---|---|
label | string? | — | Label |
description | string? | — | Helper text |
name | string? | — | Input name |
valuePlaceholder | string? | — | Value placeholder |
required | boolean? | — | Required |
inputClass | string? | — | Custom input class |
v-model: items: string[]
Emits: remove(index: number), add()
Exported from packages/ui/src/composables/:
useDeferredMount() — Defers component mounting (useful for heavy components).useTheme() — Theme management composable.