Files
moeka-project/docs/ai/context/ui-components.md
T
2026-09-06 16:28:01 +00:00

25 KiB
Raw Blame History

@proj-airi/ui Component Reference

Auto-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/


Animations

AnimatedContent

Behavior-only primitive that animates height, opacity, vertical offset, and an inner content blur from an external data-state="open|closed" lifecycle. The lifecycle owner must keep the primitive mounted until the closing animation finishes. It can compose with Reka UI content primitives through as-child, but does not depend on a specific menu, popover, or presence implementation. Visual styling remains caller-owned.

Prop Type Default Description
as PrimitiveProps['as']? 'div' Element or component rendered as the animated outer container

Slots: default

TransitionBidirectional

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

TransitionHorizontal

Horizontal slide/fade transition (0.5s hardcoded).

Props: None | Slots: default

TransitionVertical

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


Layout

Collapsible

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 })

Screen

Responsive screen component that calculates canvas dimensions based on breakpoints.

Props: None | Slots: default({ width, height })

ScrollableArea

Reka UI scroll area with shared light-mode and dark-mode scrollbar styles. The component forwards HTML attributes to the scroll-area root.

Prop Type Default Description
contentAsChild boolean? false Render the viewport content wrapper through the single default slot child
orientation 'vertical' | 'horizontal' | 'both' 'vertical' Scrollbar orientations to render
type ScrollAreaRootProps['type']? 'auto' Reka UI scrollbar visibility behavior
viewportClass string | string[]? Classes for the Reka UI viewport

Slots: default Exposed: viewport (the native scroll owner. Reka UI hides its native scrollbar and renders the configured custom track.)

Skeleton

Loading placeholder with animation.

Prop Type Default Description
animation 'pulse' | 'wave' | 'none' 'pulse' Animation style

Slots: default

Truncatable

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


Misc

BottomDrawer

Mobile modal surface built on Vaul Vue. It owns the drag handle, overlay, focus boundary, scroll region, and bottom safe area. Dragging starts only on the handle, so action buttons and scrolling do not dismiss it.

Prop Type Default Description
title string required Visible and accessible title
minimumHeight 'content' | 'half' 'content' Uses content height or at least half of the viewport height

Dismiss with the handle, overlay, or Escape. There is no close button.

v-model: boolean, defaults to false.

Slots: trigger (one button), default (drawer content).

Emits: afterClose() after the dismissal animation; closeAutoFocus(event) to prevent focus restoration when another modal opens.

Use for mobile action menus and settings panels. Desktop dialogs and panels that need snap points use their own surface.

Avatar

Shared user-avatar primitive built on Reka UI. It retries when src changes and renders the fallback when the URL is missing, loading, or fails.

Prop Type Default Description
src string | null | undefined null Avatar image URL
alt string | null | undefined null Accessible image/fallback description; omit for decorative avatars
referrerPolicy ImgHTMLAttributes['referrerpolicy']? Image referrer policy
crossOrigin ImgHTMLAttributes['crossorigin']? Image cross-origin mode

Slots: fallback (optional override for the built-in user icon)

BasicButton

Behavioral foundation for custom buttons. It owns disabled/loading behavior, press animation, sizing, icon/label rendering, and block layout, but supplies no surface, border, shape, or color styling.

Prop Type Default Description
icon string? UnoCSS/Iconify icon class
label string? Button text
disabled boolean? false Disabled state
loading boolean? false Loading state
size 'sm' | 'md' | 'lg' | 'unset' 'md' Preset size; unset leaves sizing to the caller
block boolean? false Full width

Slots: default (fallback when no label)

size="unset" omits the preset padding and text-size classes in BasicButton, Button, and GhostButton. Callers must supply any required sizing, including fixed dimensions for circular buttons.

Button

Solid general-purpose action. It has no border and shows offset outlines on hover and keyboard focus. Choose a Wind3 color family independently from its primary or secondary visual emphasis.

Includes all BasicButton props, plus:

Prop Type Default Description
shape 'rect' | 'rounded' | 'circle' | 'parallelogram' 'rect' Rectangular, pill-like, circular, or rounded angled geometry
color 'neutral' | 'primary' | 'cyan' | 'blue' | 'green' | 'lime' | 'amber' | 'red' | 'orange' | 'purple' | 'pink' 'neutral' Wind3 color family; primary follows the configured theme hue
variant 'primary' | 'secondary' 'secondary' Solid high-emphasis or subtle low-emphasis treatment
outline boolean? true Show the offset outline on hover and keyboard focus

GhostButton

Low-emphasis contextual action with a transparent default surface and compact spacing. Hover, pressed, and selected states use a subtle primary surface and text treatment without an outline. The offset outline is reserved for keyboard focus. Includes all BasicButton props.

Prop Type Default Description
active boolean? false Persist the subtle selected surface for toggle controls

IconButton

Minimal icon-only action for controls such as favorite, like, copy, or retry. It directly uses BasicButton, removes its padding, and does not add a background, outline, shape, or forced square dimensions. Supply an accessible aria-label. Props: icon, disabled, and loading.

OverlayButton

Translucent, backdrop-blurred action without an outline, intended for floating controls such as the Tamagotchi Controls Island. Includes all BasicButton props.

Callout

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

ContainerError

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()

ErrorBoundary

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()

DoubleCheckButton

Two-stage confirmation button — click once to reveal confirm/cancel.

Prop Type Default Description
color ButtonColor 'red' Confirm button color family
variant ButtonVariant 'primary' Confirm button visual emphasis
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)

Progress

Linear progress bar with animated shine.

Prop Type Default Description
progress number (required) Percentage 0100
barClass string? Custom bar color class

Form — Input

Input

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
disabled boolean? Disable editing and focus

v-model: modelValue: string | number

BasicInputFile

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 })

InputFile

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

InputFileCard

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)

InputKeyValue

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


Form — Textarea

BasicTextarea

Auto-resizing textarea with submit and paste-file events. The native row count defaults to one, so typing does not introduce a second row. Content grows when it wraps. Native rows attributes can override this minimum. When set, defaultHeight also provides the baseline for content measurement, so flex layouts do not stretch the empty measurement box.

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[])

Textarea

Styled textarea wrapping BasicTextarea.

v-model: modelValue: string


Form — Checkbox / Radio

Checkbox

Toggle switch using reka-ui SwitchRoot.

Prop Type Default Description
disabled boolean? Disabled state

v-model: modelValue: boolean

Radio

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


Form — Range

Range

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

ColorHueRange

HSL hue selector (0360) with rainbow gradient.

Prop Type Default Description
disabled boolean? Disabled

v-model: modelValue: number

RoundRange

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


Form — Select

Select

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
contentSide 'top' | 'right' | 'bottom' | 'left' 'bottom' Preferred dropdown side before collision handling
contentAlign 'start' | 'center' | 'end' 'start' Preferred dropdown alignment before collision handling
shape 'rounded' | 'default' 'default' Shape
variant 'blurry' | 'default' 'default' Variant

v-model: modelValue: T Slots: value({ option, value, placeholder }), option({ option })

SelectOption

Individual option item within Select.

Prop Type Default Description
option SelectOptionItem<T> (required) Option data

Slots: default


Form — Combobox

Combobox

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
openOnClick boolean? true Auto-open dropdown on click
contentMinWidth string | number? Dropdown min width
contentWidth string | number? Dropdown width

v-model: modelValue: T Slots: option({ option }), empty

ComboboxSelect

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
openOnClick boolean? true Auto-open dropdown on click
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

ComboboxOption

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


Form — SelectTab

SelectTab

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


Form — Field (Labeled wrappers)

All Field components wrap a base input with label, description, and consistent layout. Common slots: label, description.

FieldButton

Displays field information on the left and a compact action button on the right.

Prop Type Default Description
label string (required) Field label
description string? Helper text
buttonLabel string (required) Action button label
buttonIcon string? UnoCSS/Iconify class for the action button
disabled boolean? Prevents the action
loading boolean? Shows a spinner and prevents the action

Slots: label, description

Emits: click(event: MouseEvent)

FieldInput

Prop Type Default Description
label string? Label
description string? Helper text
placeholder string? Placeholder
required boolean? Required indicator
disabled boolean? Disable editing and focus
type InputType? Input type
autocomplete string? Native autocomplete hint
inputClass string? Custom input class
singleLine boolean? true true = input, false = textarea

v-model: modelValue: T

FieldCheckbox

Prop Type Default Description
label string? Label
description string? Helper text
disabled boolean? Disabled
placement 'left' | 'right' 'right' Switch position

v-model: modelValue: boolean

FieldTextArea

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

FieldRange

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
defaultValue number? When set, shows a reset button next to the label that restores this value. Use with as="div".

v-model: modelValue: number

FieldInputFile

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

FieldSelect

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

FieldCombobox

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
openOnClick boolean? true Auto-open dropdown on click
layout 'horizontal' | 'vertical' 'horizontal' Layout

v-model: modelValue: string Slots: label, description, option, empty

FieldKeyValues

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)

FieldValues

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()


Composables

Exported from packages/ui/src/composables/:

  • useDeferredMount() — Defers component mounting (useful for heavy components).
  • useTheme() — Theme management composable.