# Introduction Vuzeno is a complete design system for Vue, built on [Ark UI](https://ark-ui.com/){rel=""nofollow""}. You install production-ready, Tailwind-styled components into your repo with the shadcn-vue CLI, then own and customize the source. Unlike shadcn-vue (Reka UI), Vuzeno’s interactive behavior is Ark-native. ## Why Vuzeno? The Vue ecosystem, while powerful, often lacks the breadth of ready-to-use components available in React. Vuzeno aims to change that by providing carefully crafted components that solve real-world problems — the kind of components you'd otherwise build from scratch or piece together from multiple libraries. Every component is: - **Composable** — Built with a slot-based architecture for maximum flexibility - **Accessible** — Following WAI-ARIA guidelines with keyboard navigation - **Styled with Tailwind** — Leveraging Tailwind CSS 4 for consistent, customizable design - **TypeScript-first** — Full type safety out of the box ## Built On Vuzeno builds on top of excellent open-source projects: - [Ark UI](https://ark-ui.com/){rel=""nofollow""} — Headless, accessible UI primitives (the foundation of the design system) - [Tailwind CSS](https://tailwindcss.com/){rel=""nofollow""} — Utility-first CSS framework - [VueUse](https://vueuse.org/){rel=""nofollow""} — Essential Vue composition utilities - [shadcn-vue CLI](https://www.shadcn-vue.com/){rel=""nofollow""} — Registry installer used to pull components into your project (CLI only — see below) ## Why Ark UI? Ark UI powers the interactive behavior of Vuzeno components. It provides: - **Broad coverage** — Primitives for complex UI patterns (dialogs, menus, date pickers, and more) - **Accessibility** — Keyboard navigation and WAI-ARIA patterns built in - **Part-based composition** — Clean APIs that scale in real apps - **Framework-native Vue** — First-class Vue bindings with typed props and events Vuzeno wraps these primitives with Tailwind styles and opinionated composition so you get production-ready components without giving up control of the source. ### Why not shadcn-vue components? [shadcn-vue](https://www.shadcn-vue.com/){rel=""nofollow""} is built on [Reka UI](https://reka-ui.com/){rel=""nofollow""} and has no support for Ark UI. Vuzeno therefore stays detached from the shadcn-vue component library: we share only the **CLI and registry format** to install source into your project, while the design system itself is fully Ark UI-based. ## Philosophy Vue deserves a richer ecosystem. While React developers enjoy an abundance of polished components and utilities, Vue developers often find themselves building complex UI patterns from scratch. Vuzeno exists to close that gap — providing the same level of quality and developer experience that React developers take for granted, but built natively for Vue. Our goal is simple: **build a complete design system on Ark UI** and make Vue more attractive by giving developers the tools they need to ship beautiful, functional applications faster. # Getting Started ## Prerequisites Before installing Vuzeno components, make sure you have: - **Vue 3.5+** — Vuzeno uses the latest Vue features - **Tailwind CSS 4** — For styling components - **A `components.json` file** — Used by the [shadcn-vue CLI](https://www.shadcn-vue.com/){rel=""nofollow""} to know where to install files :alert{description="shadcn-vue is built on Reka UI and has no Ark UI support. Vuzeno is therefore detached from the shadcn-vue component library — we use the CLI solely as the registry installer." title="Ark UI design system, shadcn-vue CLI only" variant="info"} If you don't have a registry setup yet, run `bunx shadcn-vue@latest init` to create `components.json`, then add Vuzeno as a registry below. ## Registry setup Add Vuzeno to your `components.json` registries so you can install components with the `@vuzeno/` shorthand: ```json { "registries": { "@vuzeno": "https://vuzeno.com/r/{name}.json" } } ``` ## Installation Install components with the shadcn-vue CLI: ::installation-tabs{exec command="shadcn-vue@latest add @vuzeno/[component]"} :: Replace `[component]` with the component name (e.g. `dialog`, `phone-field`, `autocomplete`). Without registry setup, you can also install by URL: `shadcn-vue add https://vuzeno.com/r/[component].json` The CLI copies the component source and its registry dependencies into your project. Runtime packages such as `@ark-ui/vue` are installed as npm dependencies when needed. Some components also list extra npm packages on their docs (e.g. `libphonenumber-js` for Phone Field) — install those if prompted or as shown on the component page. ### Manual installation You can also copy component source code from the docs into your project. Each component page includes dependencies, source snippets, and usage examples. ## TypeScript Vuzeno is written in TypeScript and provides full type definitions. No additional configuration is required — types are inferred automatically. ## Next Steps Ready to add your first component? Browse the [components](https://vuzeno.com/docs/components) catalog, or start with: - [Dialog](https://vuzeno.com/docs/components/dialog) — Accessible modal dialogs on Ark UI - [Phone Field](https://vuzeno.com/docs/components/phone-field) — Auto-formatting and validation for phone numbers - [Autocomplete](https://vuzeno.com/docs/components/autocomplete) — Searchable combobox patterns Each component page includes installation, source, props, and usage examples. # Registries Vuzeno is one of several third-party Vue component registries offering production-ready components you can install as source into your project. Depending on your project, another registry may be a better fit — or a great complement to Vuzeno. The sections below detail each registry so you can pick the one that matches your needs. ## Inspira UI - **Link:** [inspira-ui.com](https://inspira-ui.com){rel=""nofollow""} - **Description:** Vue/Nuxt port of Aceternity UI and Magic UI — a large catalog of animated, marketing-grade components (marquees, hero effects, 3D cards, text animations, backgrounds). Reach for Inspira UI when you need flashy, motion-heavy components for landing pages and marketing sites. It's the most popular community Vue registry in this ecosystem. Install a component: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://registry.inspira-ui.com/[component].json --- :: ## UI Thing - **Link:** [uithing.com](https://uithing.com){rel=""nofollow""} - **Description:** Nuxt-first component library built on Reka UI and Tailwind, shipping an extended catalog of forms, charts, data tables, blocks, and starters. Pick UI Thing when you're building a Nuxt app and want a broader, batteries-included component library. It ships its own CLI that mirrors the registry install model. Install a component: ::installation-tabs{exec command="ui-thing@latest add [component]"} :: ## Neobrutalism Vue - **Link:** [neobrutalism-vue.com](https://neobrutalism-vue.com){rel=""nofollow""} - **Description:** 30+ neobrutalist-styled Vue components (bold borders, hard shadows, high contrast) built on Reka UI, tuned for Tailwind v4. Use it when you want the distinctive neobrutalist look with a drop-in registry — no custom CLI required. Install a component: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://neobrutalism-vue.com/r/[component].json --- :: ## ElevenLabs UI Vue - **Link:** [elevenlabs-ui-vue.com](https://elevenlabs-ui-vue.com/){rel=""nofollow""} - **Description:** Vue port of ElevenLabs UI — agent and audio components (orbs, waveforms, transcripts, voice buttons, conversation UIs) for multimodal AI apps. Reach for ElevenLabs UI Vue when you're building voice agents, audio players, or conversational AI interfaces and want polished, domain-specific components out of the box. Install a component: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://registry.elevenlabs-ui-vue.com/[component].json --- :: ## Using multiple registries You can combine any of these with Vuzeno in your `components.json` to install components with short `@namespace/` aliases: ```json { "registries": { "@vuzeno": "https://vuzeno.com/r/{name}.json", "@inspira": "https://registry.inspira-ui.com/{name}.json", "@neobrutalism": "https://neobrutalism-vue.com/r/{name}.json", "@elevenlabs": "https://registry.elevenlabs-ui-vue.com/{name}.json" } } ``` Then add components from any registry with the CLI: ::installation-tabs{exec command="shadcn-vue@latest add @inspira/[component]"} :: # Components # Accordion :component-preview{component="accordion" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/accordion.json --- :: ## Usage ```vue ``` ## Composition ```text Accordion.Root ├── Accordion.Context ├── Accordion.ItemContent ├── Accordion.ItemContext ├── Accordion.ItemIndicator ├── Accordion.ItemTrigger ├── Accordion.Item ├── Accordion.RootProvider ``` ## Examples ### Default Value Set the `defaultValue` prop to specify which item should be expanded by default. :component-preview{component="accordion" name="default-value"} ### Controlled Use the `value` and `onValueChange` props to control the expanded items. :component-preview{component="accordion" name="controlled"} ### Root Provider An alternative way to control the accordion is to use the `RootProvider` component and the `useAccordion` hook. This way you can access the state and methods from outside the component. :component-preview{component="accordion" name="root-provider"} ### Collapsible Use the `collapsible` prop to allow the user to collapse all panels. :component-preview{component="accordion" name="collapsible"} ### Multiple Use the `multiple` prop to allow multiple panels to be expanded simultaneously. :component-preview{component="accordion" name="multiple"} ### Horizontal By default, the Accordion is oriented vertically. Use the `orientation` prop to switch to a horizontal layout. :component-preview{component="accordion" name="horizontal"} ### Lazy Mount Use the `lazyMount` prop to defer rendering of accordion content until the item is expanded. Combine with `unmountOnExit` to unmount content when collapsed, freeing up resources. :component-preview{component="accordion" name="lazy-mount"} ### Context Use `Accordion.Context` or `useAccordionContext` to access the accordion state. :component-preview{component="accordion" name="context"} ### Item State Use `Accordion.ItemContext` or `useAccordionItemContext` to access the state of an accordion item. :component-preview{component="accordion" name="item-context"} ## API See [Ark UI Accordion docs](https://ark-ui.com/vue/docs/components/accordion){rel=""nofollow""} for full props and examples. # ActionSheet :component-preview{component="action-sheet" name="basic"} ## Features - **Zag state machine** — Open/close, dismiss, option selection, and cancel are modeled with a custom `@zag-js` machine (not Ark Dialog) - **Programmatic API** — Define the action sheet with `useActionSheet()`, pass it to `ActionSheet.Provider`, then `await show()` for a typed result (`ActionSheetStartResult`) when the user picks an option, cancels, or dismisses the sheet - **Classic usage** — Control visibility with `v-model:open` and open via `ActionSheet.Trigger` - **Composable layout** — Stack multiple `ActionSheet.Group` blocks for separated groups of actions ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/action-sheet.json --- :: ## Usage ```vue ``` ## Composition ```text ActionSheet.Root ├── ActionSheet.Trigger └── ActionSheet.Content ├── ActionSheet.Group │ └── ActionSheet.Option └── ActionSheet.Cancel ActionSheet.Provider └── ActionSheet.Content ├── ActionSheet.Group │ └── ActionSheet.Option └── ActionSheet.Cancel ``` ## Examples ### Classic action sheet Use `ActionSheet.Trigger` to open the sheet and `ActionSheet.Option` for each choice. `ActionSheet.Cancel` fires the cancel path (and closes the sheet). :component-preview{component="action-sheet" name="basic"} ### Provider API Define the action sheet with `useActionSheet()`, then pass it to `ActionSheet.Provider` to drive it programmatically. Call `show()` and `await` the result — the promise resolves when the user selects an option, taps cancel, or closes the overlay (when `closeOnClickOutside` is enabled). ```vue showLineNumbers ``` ### Multiple option groups Compose several `ActionSheet.Group` components inside `ActionSheet.Content` to separate primary actions from secondary ones. ```vue showLineNumbers ``` ## API Reference ### ActionSheet.Root | Prop | Type | Default | | --------------------- | --------- | ------- | | `open` | `boolean` | `false` | | `closeOnClickOutside` | `boolean` | `true` | | `showOverlay` | `boolean` | `true` | | `closeOnEscape` | `boolean` | `true` | ### ActionSheet.Provider | Prop | Type | Default | | ------- | ---------------- | ------- | | `value` | `ActionSheetApi` | — | Takes the object returned by `useActionSheet()` and drives the sheet's open state and callbacks from it. ### useActionSheet ```ts function useActionSheet(props?: { showOverlay?: boolean; closeOnClickOutside?: boolean; closeOnEscape?: boolean; open?: boolean; defaultOpen?: boolean; onOpenChange?: (details: { open: boolean }) => void; onSelectOption?: (details: { value: unknown }) => void; onCancel?: () => void; onDismiss?: () => void; }): ComputedRef; ``` Returns a computed `ActionSheetApi` with: | Member | Type | Description | | --------------- | --------------------------------------- | -------------------------------------------------------------------------------------- | | `show()` | `() => Promise` | Opens the sheet and resolves when the user selects an option, cancels, or dismisses it | | `close()` | `() => void` | Closes the sheet | | `setOpen(open)` | `(open: boolean) => void` | Opens or closes the sheet | | `open` | `boolean` | Current open state | ### ActionSheetStartResult ```ts type ActionSheetStartResult = | { cancelled: false; cancelledReason: null; selectedOption: O } | { cancelled: true; cancelledReason: "cancel" | "close"; selectedOption: null } ``` # Alert :component-preview{component="alert" name="basic"} ## Features - **Composable** — Flexible slot-based layout with `Alert.Icon`, `Alert.Title`, and `Alert.Description` - **Variants** — `default`, `info`, `success`, `warning`, and `destructive` styles - **Accessible** — Uses `role="alert"` for screen reader announcements - **Icon support** — `Alert.Icon` renders a variant-aware icon automatically ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/alert.json --- :: ## Usage ```vue ``` ## Composition ```text Alert.Root ├── Alert.Icon ├── Alert.Title └── Alert.Description ``` ## Examples ### With icon `Alert.Icon` picks the icon from the root `variant`. :component-preview{component="alert" name="with-icon"} ### Variants All semantic variants with their default icons. :component-preview{component="alert" name="variants"} ### Destructive Use `variant="destructive"` for error or critical messages. :component-preview{component="alert" name="destructive"} ## API | Part | Description | | ------------------- | ------------------------------------------------------------- | | `Alert.Root` | Root container with `role="alert"`. Supports `variant` prop | | `Alert.Icon` | Variant-aware icon (`size-3.5`). Inherits `variant` from root | | `Alert.Title` | Alert heading | | `Alert.Description` | Supporting text or rich content | ### Variants | Variant | Icon | Description | | ------------- | -------------- | ----------------------------------------- | | `default` | Bell | Neutral callout for general information | | `info` | Info | Informational message with blue styling | | `success` | Circle check | Positive confirmation or completed action | | `warning` | Triangle alert | Caution or attention needed | | `destructive` | Circle alert | Error or critical failure state | # Alert Dialog :component-preview{component="alert-dialog" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/alert-dialog.json --- :: ## Usage ```vue ``` Alert Dialog is a pre-configured variant of [Dialog](https://vuzeno.com/docs/components/dialog) with `role="alertdialog"`. It hides the close button in the content panel and is intended for confirmations where the user must explicitly choose an action. Compared to a regular dialog: - **Automatic focus** — the cancel/close action receives focus when opened, prioritizing the safest choice - **Explicit dismissal** — cannot be closed by clicking outside; only button clicks or the Escape key dismiss it ## Composition ```text AlertDialog.Root ├── AlertDialog.Trigger └── AlertDialog.Content ├── AlertDialog.Header │ ├── AlertDialog.Title │ └── AlertDialog.Description └── AlertDialog.Footer ├── AlertDialog.Cancel └── AlertDialog.Confirm ``` ## API Props, events, and hooks match Ark UI Dialog. See [Ark UI Dialog docs](https://ark-ui.com/vue/docs/components/dialog){rel=""nofollow""} for the full API. ```ts import { AlertDialog, useDialog, useDialogContext, dialogAnatomy, } from "@/components/ui/alert-dialog"; ``` # Angle Slider :component-preview{component="angle-slider" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/angle-slider.json --- :: ## Usage ```vue ``` ## Composition ```text AngleSlider.Root ├── AngleSlider.Context ├── AngleSlider.Control ├── AngleSlider.HiddenInput ├── AngleSlider.Label ├── AngleSlider.MarkerGroup ├── AngleSlider.Marker ├── AngleSlider.RootProvider ├── AngleSlider.Thumb ├── AngleSlider.ValueText ``` ## Examples ### Controlled Use the `value` and `onValueChange` props to control the value of the Angle Slider. :component-preview{component="angle-slider" name="controlled"} ### Steps Use the `step` prop to set the discrete steps of the Angle Slider. :component-preview{component="angle-slider" name="steps"} ## API See [Ark UI Angle Slider docs](https://ark-ui.com/vue/docs/components/angle-slider){rel=""nofollow""} for full props and examples. # Autocomplete :component-preview{component="autocomplete" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/autocomplete.json --- :: ## Usage ```vue ``` ## Composition ```text Autocomplete.Root ├── Autocomplete.Label ├── Autocomplete.Control │ ├── Autocomplete.Input │ ├── Autocomplete.Indicators │ │ ├── Autocomplete.ClearTrigger │ │ └── Autocomplete.Trigger │ └── Autocomplete.Tags ├── Autocomplete.Content │ ├── Autocomplete.Empty │ ├── Autocomplete.Status │ ├── Autocomplete.ItemGroup │ │ ├── Autocomplete.ItemGroupLabel │ │ └── Autocomplete.Item │ └── Autocomplete.Scroller ├── Autocomplete.Context └── Autocomplete.RootProvider ``` ## Examples ### Auto Highlight Automatically highlight the first matching item as the user types by setting `inputBehavior="autohighlight"`. :component-preview{component="autocomplete" name="auto-highlight"} ### Inline Autocomplete Complete the input value with the first matching item by setting `inputBehavior="autocomplete"`. Use with `startsWith` filter for best results. :component-preview{component="autocomplete" name="inline-autocomplete"} ### Grouping To group related autocomplete items, use the `groupBy` prop on the collection and `collection.group()` to iterate the groups. :component-preview{component="autocomplete" name="grouping"} ### Field The `Field` component helps manage form-related state and accessibility attributes of an autocomplete. It includes handling ARIA labels, helper text, and error text to ensure proper accessibility. :component-preview{component="autocomplete" name="field"} ### Context Access the autocomplete's state with `Autocomplete.Context` or the `useAutocompleteContext` hook—useful for displaying the selected value or building custom UI. :component-preview{component="autocomplete" name="context"} ### Root Provider An alternative way to control the autocomplete is to use the `RootProvider` component and the `useAutocomplete` hook. This way you can access the state and methods from outside the component. :component-preview{component="autocomplete" name="root-provider"} ### Links Use the `asChild` prop to render the autocomplete items as links. :component-preview{component="autocomplete" name="links"} ### Rehydrate When an autocomplete has a `defaultValue` or `value` but the `collection` is not loaded yet, you can rehydrate the value to populate the input. :component-preview{component="autocomplete" name="rehydrate"} ### Highlight Text Highlight the matching search text in autocomplete items based on the user's input. :component-preview{component="autocomplete" name="highlight-text"} ### Dynamic Generate autocomplete items dynamically based on user input. This is useful for creating suggestions or autocomplete functionality. :component-preview{component="autocomplete" name="dynamic"} ### Creatable Allow users to create new options when their search doesn't match any existing items. This is useful for tags, categories, or other custom values. :component-preview{component="autocomplete" name="creatable"} ### Multiple Selection Enable multiple selection by setting the `multiple` prop. Selected items can be displayed as tags above the input. :component-preview{component="autocomplete" name="multiple-selection"} ### Async Search Load options asynchronously based on user input using the `useAsyncList` hook. This is useful for searching large datasets or fetching data from an API. :component-preview{component="autocomplete" name="async-search"} ### Virtualized For very large lists, use virtualization with `@tanstack/virtual` to render only the visible items. Pass the `scrollToIndexFn` prop to enable keyboard navigation within the virtualized list. :component-preview{component="autocomplete" name="virtualized"} ### Custom Object Use the `itemToString` and `itemToValue` props to map custom objects to the required interface. :component-preview{component="autocomplete" name="custom-object"} ### Limit Results Use the `limit` property on `useListCollection` to limit the number of rendered items in the DOM. :component-preview{component="autocomplete" name="limit-results"} ## API See [Ark UI Combobox docs](https://ark-ui.com/vue/docs/components/combobox){rel=""nofollow""} for full props and examples. # Avatar :component-preview{component="avatar" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/avatar.json --- :: ## Usage ```vue ``` ## Composition ```text Avatar.Group └── Avatar.Root ├── Avatar.Fallback └── Avatar.Image Avatar.Root ├── Avatar.Context ├── Avatar.Fallback ├── Avatar.Image ├── Avatar.RootProvider ``` ## Examples ### Sizes Use the `size` prop on `Avatar.Root` to change the size of the avatar. :component-preview{component="avatar" name="sizes"} ### Group Stack multiple avatars using `Avatar.Group`. Apply negative spacing and ring utilities on each `Avatar.Root` to create an overlapping effect. :component-preview{component="avatar" name="group"} ## API See [Ark UI Avatar docs](https://ark-ui.com/vue/docs/components/avatar){rel=""nofollow""} for full props and examples. ### Avatar.Root | Prop | Type | Default | Description | | ------- | ------------------------- | ----------- | ---------------------- | | `size` | `"sm" | "default" | "lg"` | `"default"` | Size of the avatar | | `class` | `string` | — | Additional CSS classes | ### Avatar.Group | Prop | Type | Default | Description | | ------------- | --------------------------- | -------------- | ----------------------------- | | `orientation` | `"horizontal" | "vertical"` | `"horizontal"` | Layout direction of the group | | `class` | `string` | — | Additional CSS classes | # Badge :component-preview{component="badge" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/badge.json --- :: ## Usage ```vue ``` ## Examples ### Variants Use the `variant` prop to change the visual style of the badge. :component-preview{component="badge" name="variants"} # Breadcrumb :component-preview{component="breadcrumb" name="basic"} ## Features - **Composable** — Flexible slot-based layout with `Breadcrumb.List`, `Breadcrumb.Item`, `Breadcrumb.Link`, `Breadcrumb.Page`, and `Breadcrumb.Separator` - **Accessible** — Semantic navigation with `aria-current` on the current page - **Customizable** — Override separators, compose with menus, or collapse long paths with `Breadcrumb.Ellipsis` ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/breadcrumb.json --- :: ## Usage ```vue ``` ## Composition ```text Breadcrumb.Root └── Breadcrumb.List ├── Breadcrumb.Item │ └── Breadcrumb.Link ├── Breadcrumb.Separator ├── Breadcrumb.Item │ └── Breadcrumb.Link ├── Breadcrumb.Separator └── Breadcrumb.Item └── Breadcrumb.Page ``` ## Examples ### Custom separator Use a custom icon or character inside `Breadcrumb.Separator`. :component-preview{component="breadcrumb" name="custom-separator"} ### Dropdown Compose `Breadcrumb.Item` with `Menu` to create a dropdown for nested navigation. :component-preview{component="breadcrumb" name="dropdown"} ### Collapsed Use `Breadcrumb.Ellipsis` to collapse intermediate path segments. :component-preview{component="breadcrumb" name="ellipsis"} ## API | Part | Description | | ---------------------- | ---------------------------------------------------------- | | `Breadcrumb.Root` | Root `nav` element with `aria-label="breadcrumb"` | | `Breadcrumb.List` | Ordered list of breadcrumb items | | `Breadcrumb.Item` | List item wrapping a link or page label | | `Breadcrumb.Link` | Navigable link. Supports `as-child` for router links | | `Breadcrumb.Page` | Current page label with `aria-current="page"` | | `Breadcrumb.Separator` | Visual separator between items. Defaults to a chevron icon | | `Breadcrumb.Ellipsis` | Collapsed path indicator with screen-reader text | # Button :component-preview{component="button" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/button.json --- :: ## Usage ```vue ``` ## Examples ### Variants Use the `variant` prop to change the visual style of the button. :component-preview{component="button" name="variants"} ### Sizes Use the `size` prop to change the size of the button. :component-preview{component="button" name="sizes"} ### Disabled Use the native `disabled` attribute to disable the button. :component-preview{component="button" name="disabled"} # Button Group :component-preview{component="button-group" name="basic"} ## Features - **Grouped layout** — Visually connects adjacent buttons by removing inner border radii - **Orientation** — Horizontal (default) or vertical layout via the `orientation` prop - **Composable** — Nest groups or combine with inputs and other controls - **Accessible** — Renders as a semantic `fieldset` via Ark UI's polymorphic factory ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/button-group.json --- :: ## Usage ```vue ``` ## Composition ```text ButtonGroup └── Button ``` ## Accessibility - The component renders as a `fieldset` element. - Use Tab to navigate between focusable elements in the group. - Label the group with `aria-label` or `aria-labelledby`. ```vue ``` ## Button Group vs Toggle Group - Use **Button Group** when buttons perform independent actions. - Use [Toggle Group](https://vuzeno.com/docs/components/toggle-group) when buttons toggle a shared state. ## Examples ### Orientation Set the `orientation` prop to change the layout. :component-preview{component="button-group" name="orientation"} ### Sizes Control the size of buttons using the `size` prop on individual buttons. :component-preview{component="button-group" name="sizes"} ### Nested Nest `ButtonGroup` components to create groups with spacing between them. :component-preview{component="button-group" name="nested"} ### Input Combine an input with action buttons in a single group. :component-preview{component="button-group" name="input"} ### Select Pair a select with an input and submit button — useful for amount or unit pickers. :component-preview{component="button-group" name="select"} ### Dropdown Create a split button group with a [Menu](https://vuzeno.com/docs/components/menu) for secondary actions. :component-preview{component="button-group" name="dropdown"} ## API ### ButtonGroup | Prop | Type | Default | Description | | ------------- | --------------------------- | -------------- | ---------------------------------- | | `orientation` | `"horizontal" | "vertical"` | `"horizontal"` | Layout direction of the group | | `asChild` | `boolean` | `false` | Merge props onto the child element | | `class` | `string` | — | Additional CSS classes | The component also exports `buttonGroupVariants` and `ButtonGroupVariants` for building custom styled wrappers. See [Ark UI composition guide](https://ark-ui.com/docs/guides/composition){rel=""nofollow""} for polymorphic usage with `asChild`. # Card :component-preview{component="card" name="basic"} ## Features - **Composable** — Flexible slot-based layout with `Card.Header`, `Card.Title`, `Card.Description`, `Card.Content`, and `Card.Footer` - **Styled primitives** — Opinionated defaults for borders, spacing, and typography - **Customizable** — Override any part with the `class` prop ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/card.json --- :: ## Composition ```text Card.Root ├── Card.Header │ ├── Card.Title │ └── Card.Description ├── Card.Content └── Card.Footer ``` ## Usage ```vue ``` ## Examples ### With form Use a card to group related form fields and actions. :component-preview{component="card" name="form"} # Carousel :component-preview{component="carousel" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/carousel.json --- :: ## Usage ```vue ``` ## Composition ```text Carousel.Root ├── Carousel.AutoplayIndicator ├── Carousel.ProgressText ├── Carousel.AutoplayTrigger ├── Carousel.Context ├── Carousel.Control ├── Carousel.IndicatorGroup ├── Carousel.Indicator ├── Carousel.ItemGroup ├── Carousel.Item ├── Carousel.NextTrigger ├── Carousel.PrevTrigger ├── Carousel.RootProvider ``` ## Examples ### Controlled To create a controlled Carousel component, you can manage the state of the carousel using the `page` prop and update it when the `onPageChange` event handler is called: :component-preview{component="carousel" name="controlled"} ### Root Provider An alternative way to control the carousel is to use the `RootProvider` component and the `useCarousel` hook. This way you can access the state and methods from outside the component. :component-preview{component="carousel" name="root-provider"} ### Autoplay Pass the `autoplay` and `loop` props to `Carousel.Root` to make the carousel play automatically. :component-preview{component="carousel" name="autoplay"} ### Pause on Hover This feature isn't built-in, but you can use the `play()` and `pause()` methods from `Carousel.Context` to implement pause on hover. :component-preview{component="carousel" name="pause-on-hover"} ### Thumbnail Indicators Replace default indicator dots with image thumbnails. Render each thumbnail inside `Carousel.Indicator` to create a visual preview of each slide: :component-preview{component="carousel" name="thumbnail-indicators"} ### Vertical Add the `orientation="vertical"` prop to `Carousel.Root` to switch the carousel to vertical scrolling. This can be helpful for displaying vertical galleries or content feeds. :component-preview{component="carousel" name="vertical"} ### Dynamic Manage slides dynamically by storing them in state and syncing the carousel page. Pass the `page` prop and `onPageChange` handler to `Carousel.Root`, and update `slideCount` when slides are added or removed. This demonstrates bidirectional state synchronization between your component state and the carousel. :component-preview{component="carousel" name="dynamic"} ### Scroll to Slide Use `Carousel.Context` to access the carousel API and call `api.scrollToIndex(index)` to programmatically navigate to a specific slide. This is useful for creating custom navigation or jump-to-slide functionality. :component-preview{component="carousel" name="scroll-to-slide"} ### Slides Per Page Display multiple slides simultaneously by setting the `slidesPerPage` prop on `Carousel.Root`. Use `api.pageSnapPoints` from `Carousel.Context` to render the correct number of indicators based on pages rather than individual slides. Add the `spacing` prop to control the gap between slides. :component-preview{component="carousel" name="slides-per-page"} ### Spacing Control the gap between slides using the `spacing` prop on `Carousel.Root`. Combine it with `slidesPerPage` to create layouts that show partial previews of adjacent slides. :component-preview{component="carousel" name="spacing"} ### Variable Sizes To allow slides with different widths, set the `autoSize` prop on `Carousel.Root`. This lets each `Carousel.Item` define its own width, and the carousel will adjust automatically. You can also use the `snapAlign` prop on individual items to control where each one snaps into view. :component-preview{component="carousel" name="variable-sizes"} ## API See [Ark UI Carousel docs](https://ark-ui.com/vue/docs/components/carousel){rel=""nofollow""} for full props and examples. # Checkbox :component-preview{component="checkbox" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/checkbox.json --- :: ## Usage ```vue ``` ## Composition ```text Checkbox.Root ├── Checkbox.Context ├── Checkbox.Control ├── Checkbox.Group ├── Checkbox.GroupProvider ├── Checkbox.HiddenInput ├── Checkbox.Indicator ├── Checkbox.Label ├── Checkbox.RootProvider ``` ## Examples ### Default Checked Use the `defaultChecked` prop to set the initial checked state in an uncontrolled manner. The checkbox will manage its own state internally. :component-preview{component="checkbox" name="default-checked"} ### Controlled Use the `checked` and `@checked-change` props to programmatically control the checkbox's state. :component-preview{component="checkbox" name="controlled"} ### Root Provider An alternative way to control the checkbox is to use the `RootProvider` component and the `useCheckbox` hook. This way you can access the state and methods from outside the component. :component-preview{component="checkbox" name="root-provider"} ### Disabled Use the `disabled` prop to make the checkbox non-interactive. :component-preview{component="checkbox" name="disabled"} ### Indeterminate Use the `indeterminate` prop to create a checkbox in an indeterminate state (partially checked). :component-preview{component="checkbox" name="indeterminate"} ### Checkbox Group Use the `Checkbox.Group` component to manage a group of checkboxes. The `Checkbox.Group` component manages the state of the checkboxes and provides a way to access the checked values. :component-preview{component="checkbox" name="group"} ### Group Controlled Use `v-model` (or the `model-value` prop with the `@value-change` event) to programmatically control the checkbox group's state. This example demonstrates how to manage selected checkboxes in an array and display the current selection. :component-preview{component="checkbox" name="group-controlled"} ### Group Provider Use the `useCheckboxGroup` hook to create the checkbox group store and pass it to the `Checkbox.GroupProvider` component. This provides maximum control over the group programmatically, similar to how `RootProvider` works for individual checkboxes. :component-preview{component="checkbox" name="group-provider"} ### Invalid Use the `invalid` prop on `Checkbox.Group` to mark the entire group as invalid for validation purposes. This applies the invalid state to all checkboxes within the group. :component-preview{component="checkbox" name="group-invalid"} ### Max Selected Use the `maxSelectedValues` prop to limit the number of checkboxes that can be selected at once. Once the maximum is reached, remaining checkboxes become disabled. :component-preview{component="checkbox" name="group-max-selected"} ### Select All Implement a "select all" checkbox that controls all checkboxes within a group. The parent checkbox automatically shows an indeterminate state when some (but not all) items are selected, and becomes fully checked when all items are selected. :component-preview{component="checkbox" name="select-all"} ## API See [Ark UI Checkbox docs](https://ark-ui.com/vue/docs/components/checkbox){rel=""nofollow""} for full props and examples. # Clipboard :component-preview{component="clipboard" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/clipboard.json --- :: ## Usage ```vue ``` ## Composition ```text Clipboard.Root ├── Clipboard.Label ├── Clipboard.Control │ ├── Clipboard.Input │ └── Clipboard.Trigger │ └── Clipboard.Indicator ├── Clipboard.Context ├── Clipboard.RootProvider └── Clipboard.ValueText ``` ## Examples ### Controlled Control the clipboard value externally by managing the state yourself and using `onValueChange` to handle updates. :component-preview{component="clipboard" name="controlled"} ### Root Provider An alternative way to control the clipboard is to use the `RootProvider` component and the `useClipboard` hook. This way you can access the state and methods from outside the component. :component-preview{component="clipboard" name="root-provider"} ### Context Access the clipboard's state with `Clipboard.Context` or the `useClipboardContext` hook. You get properties like `copied`, `value`, and `setValue`. :component-preview{component="clipboard" name="context"} ### Copy Status Use the `onStatusChange` prop to listen for copy operations. It exposes a `copied` property that you can use to display a success message. :component-preview{component="clipboard" name="copy-status"} ### Timeout Configure the copy status timeout duration using the `timeout` prop. Default is 3000ms (3 seconds). :component-preview{component="clipboard" name="timeout"} ### Value Text Use `Clipboard.ValueText` to display the current clipboard value. :component-preview{component="clipboard" name="value-text"} ## API See [Ark UI Clipboard docs](https://ark-ui.com/vue/docs/components/clipboard){rel=""nofollow""} for full props and examples. # Collapsible :component-preview{component="collapsible" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/collapsible.json --- :: ## Usage ```vue ``` ## Composition ```text Collapsible.Root ├── Collapsible.Trigger │ └── Collapsible.Indicator ├── Collapsible.Content │ └── Collapsible.Body ├── Collapsible.Context └── Collapsible.RootProvider ``` ## Examples ### Disabled Use the `disabled` prop to disable the collapsible and prevent it from being toggled. :component-preview{component="collapsible" name="disabled"} ### Partial Collapse Use the `collapsedHeight` or `collapsedWidth` props to create a "show more/less" pattern. When set, the content maintains the specified dimensions when collapsed instead of collapsing to 0px. We expose the `--collapsed-height` or `--collapsed-width` variables to use in your CSS animations. :component-preview{component="collapsible" name="partial-collapse"} ### Nested Collapsibles You can nest collapsibles within collapsibles to create hierarchical content structures. :component-preview{component="collapsible" name="nested"} ### Lazy Mount Use `lazyMount` to delay mounting the content until first opened, and `unmountOnExit` to remove it from the DOM when collapsed. Combining both ensures the component is only in the DOM while expanded. :component-preview{component="collapsible" name="lazy-mount"} ### Root Provider An alternative way to control the collapsible is to use the `RootProvider` component and the `useCollapsible` hook. This way you can access the state and methods from outside the component. :component-preview{component="collapsible" name="root-provider"} ## API See [Ark UI Collapsible docs](https://ark-ui.com/vue/docs/components/collapsible){rel=""nofollow""} for full props and examples. # Color Picker :component-preview{component="color-picker" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/color-picker.json --- :: ## Usage ```vue ``` ## Composition ```text ColorPicker.Root ├── ColorPicker.AreaBackground ├── ColorPicker.AreaThumb ├── ColorPicker.Area ├── ColorPicker.ChannelInput ├── ColorPicker.ChannelSliderLabel ├── ColorPicker.ChannelSliderThumb ├── ColorPicker.ChannelSliderTrack ├── ColorPicker.ChannelSliderValueText ├── ColorPicker.ChannelSlider ├── ColorPicker.Content ├── ColorPicker.Context ├── ColorPicker.Control ├── ColorPicker.EyeDropperTrigger ├── ColorPicker.FormatSelect ├── ColorPicker.FormatTrigger ├── ColorPicker.HiddenInput ├── ColorPicker.Label ├── ColorPicker.Positioner ├── ColorPicker.RootProvider ├── ColorPicker.SwatchGroup ├── ColorPicker.SwatchIndicator ├── ColorPicker.SwatchTrigger ├── ColorPicker.Swatch ├── ColorPicker.TransparencyGrid ├── ColorPicker.Trigger ├── ColorPicker.ValueSwatch ├── ColorPicker.ValueText ├── ColorPicker.View ``` ## Examples ### Controlled Use the `value` and `onValueChange` props to programatically control the color picker's state. :component-preview{component="color-picker" name="controlled"} ### Open Controlled Control the open state of the color picker popover programmatically using the `open` and `onOpenChange` props. :component-preview{component="color-picker" name="open-controlled"} ### Root Provider An alternative way to control the color picker is to use the `RootProvider` component and the `useColorPicker` hook. This way you can access the state and methods from outside the component. :component-preview{component="color-picker" name="root-provider"} ### Disabled Use the `disabled` prop to disable the color picker. :component-preview{component="color-picker" name="disabled"} ### Inline Render the color picker inline without a popover by using the `inline` prop. :component-preview{component="color-picker" name="inline"} ### Input Only A minimal color picker with just an input field, value swatch, and eye dropper trigger. :component-preview{component="color-picker" name="input-only"} ### Slider Only Display only the channel sliders for RGB color selection. :component-preview{component="color-picker" name="slider-only"} ### Swatch Only A simple color picker with only preset color swatches. :component-preview{component="color-picker" name="swatch-only"} ### Swatches Include preset color swatches in the color picker content for quick color selection. :component-preview{component="color-picker" name="swatches"} ### Value Swatch Display the current color value as a swatch alongside the color area and sliders. :component-preview{component="color-picker" name="value-swatch"} ### Field The `Field` component helps manage form-related state and accessibility attributes of a color picker. It includes handling ARIA labels, helper text, and error text to ensure proper accessibility. :component-preview{component="color-picker" name="field"} ### Form Usage Integrate the color picker with form libraries like React Hook Form using the `HiddenInput` component. :component-preview{component="color-picker" name="form-usage"} ### Inside Dialog Here's an example of how to use the color picker inside a dialog. :component-preview{component="color-picker" name="inside-dialog"} ## API See [Ark UI Color Picker docs](https://ark-ui.com/vue/docs/components/color-picker){rel=""nofollow""} for full props and examples. # Date Input :component-preview{component="date-input" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/date-input.json --- :: ## Usage ```vue ``` ## Composition ```text DateInput.Root ├── DateInput.Label ├── DateInput.Control │ └── DateInput.SegmentGroup │ └── DateInput.Segment ├── DateInput.HiddenInput ├── DateInput.Context ├── DateInput.SegmentContext └── DateInput.RootProvider ``` ## Examples ### Default Value Use the `defaultValue` prop with `parseDate` to set the initial date value. :component-preview{component="date-input" name="default-value"} ### Controlled Use the `value` and `onValueChange` props to control the date input's value programmatically. :component-preview{component="date-input" name="controlled"} ### Root Provider An alternative way to control the date input is to use the `RootProvider` component and the `useDateInput` hook. This way you can access the state and methods from outside the component. :component-preview{component="date-input" name="root-provider"} ### Granularity Use the `granularity` prop to control which date fields are displayed. Supported values are `day`, `hour`, `minute`, and `second`. :component-preview{component="date-input" name="granularity"} ### Time Only To create a time-only input, set `granularity` to `minute` (or `second`) and provide a `formatter` that only includes time fields. Use the `hourCycle` prop to switch between 12 and 24 hour formats. :component-preview{component="date-input" name="time-only"} ### Range To create a date input that allows a range selection, set the `selectionMode` prop to `range` and render two `SegmentGroup` components with `index` props set to `0` and `1`. :component-preview{component="date-input" name="range"} ### Min and Max Use the `min` and `max` props with `parseDate` to restrict the selectable date range. Dates outside this range will be marked as invalid. :component-preview{component="date-input" name="min-max"} ### Disabled Use the `disabled` prop to prevent user interaction with the date input. :component-preview{component="date-input" name="disabled"} ### Read Only Use the `readOnly` prop to make the date input non-editable while still being focusable. :component-preview{component="date-input" name="read-only"} ### Invalid Use the `invalid` prop to indicate an error state on the date input. :component-preview{component="date-input" name="invalid"} ### Leading Zeros Use the `shouldForceLeadingZeros` prop to toggle whether numeric segments are padded with a leading zero. :component-preview{component="date-input" name="leading-zeros"} ### Localized Use the `locale` prop to set the language and regional formatting of the date segments. :component-preview{component="date-input" name="localized"} ### RTL Set the `dir` prop to `rtl` for right-to-left language support. :component-preview{component="date-input" name="rtl"} ### With Clear Button Use `useDateInput` via `RootProvider` to access the `clearValue` method and render a clear button alongside the input. :component-preview{component="date-input" name="with-clear-button"} ### With Date Picker Combine `DateInput` with `DatePicker` by syncing their values using `onValueChange` to provide both typed and calendar-based date selection. :component-preview{component="date-input" name="with-date-picker"} ## API See [Ark UI Date Input docs](https://ark-ui.com/vue/docs/components/date-input){rel=""nofollow""} for full props and examples. # Date Picker :component-preview{component="date-picker" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/date-picker.json --- :: ## Usage ```vue ``` Use `DatePicker.Calendar` for the default day / month / year views, or compose `DatePicker.DayView`, `DatePicker.MonthView`, and `DatePicker.YearView` individually. All Ark UI primitives remain available for custom layouts. ## Composition ```text DatePicker.Root ├── DatePicker.ClearTrigger ├── DatePicker.Content │ └── DatePicker.Calendar │ ├── DatePicker.DayView │ ├── DatePicker.MonthView │ └── DatePicker.YearView ├── DatePicker.Context ├── DatePicker.Control ├── DatePicker.Input ├── DatePicker.Label ├── DatePicker.MonthSelect ├── DatePicker.NextTrigger ├── DatePicker.Positioner ├── DatePicker.PresetTrigger ├── DatePicker.PrevTrigger ├── DatePicker.RangeText ├── DatePicker.ValueText ├── DatePicker.RootProvider ├── DatePicker.TableBody ├── DatePicker.TableCellTrigger ├── DatePicker.TableCell ├── DatePicker.TableHead ├── DatePicker.TableHeader ├── DatePicker.TableRow ├── DatePicker.Table ├── DatePicker.Trigger ├── DatePicker.ViewControl ├── DatePicker.ViewNav ├── DatePicker.ViewTrigger ├── DatePicker.View ├── DatePicker.WeekNumberHeaderCell ├── DatePicker.WeekNumberCell ├── DatePicker.YearSelect ``` ## Examples ### Default Value Use the `defaultValue` prop with `parseDate` to set the initial date value. :component-preview{component="date-picker" name="default-value"} ### Controlled Use the `value` and `onValueChange` props to control the date picker's value programmatically. :component-preview{component="date-picker" name="controlled"} ### Root Provider An alternative way to control the date picker is to use the `RootProvider` component and the `useDatePicker` hook. This way you can access the state and methods from outside the component. :component-preview{component="date-picker" name="root-provider"} ### Default View Use the `defaultView` prop to set which view (day, month, or year) the calendar opens to initially. :component-preview{component="date-picker" name="default-view"} ### Month and Year Select Use `MonthSelect` and `YearSelect` components to create a header with dropdown selects for quick month/year navigation, alongside the prev/next triggers. :component-preview{component="date-picker" name="month-and-year-select"} ### Range To create a date picker that allows a range selection, you need to: - Set the `selectionMode` prop to `range`. - Render multiple inputs with the `index` prop set to `0` and `1`. :component-preview{component="date-picker" name="range"} ### Multiple Use the `selectionMode="multiple"` prop to allow selecting multiple dates. This example also shows how to display selected dates as removable tags. :component-preview{component="date-picker" name="multiple"} ### Max Selected Dates Use the `maxSelectedDates` prop with `selectionMode="multiple"` to limit the number of dates that can be selected. In this example, users can select up to 3 dates. :component-preview{component="date-picker" name="max-selected-dates"} ### Multiple Months To create a date picker that displays multiple months side by side: - Set the `numOfMonths` prop to the number of months you want to display. - Use the `datePicker.getOffset({ months: 1 })` to get data for the next month. :component-preview{component="date-picker" name="multiple-months"} ### Presets Use the `DatePicker.PresetTrigger` component to add quick-select preset options like "Last 7 days" or "This month". :component-preview{component="date-picker" name="presets"} ### Min and Max Use the `min` and `max` props with `parseDate` to restrict the selectable date range. Dates outside this range will be disabled. :component-preview{component="date-picker" name="min-and-max"} ### Unavailable Use the `isDateUnavailable` prop to mark specific dates as unavailable. This example disables weekends. :component-preview{component="date-picker" name="unavailable"} ### Locale Use the `locale` prop to set the language and formatting, and `startOfWeek` to set the first day of the week (0 = Sunday, 1 = Monday, etc.). :component-preview{component="date-picker" name="locale"} ### Month Picker Create a month-only picker by setting `defaultView="month"` and `minView="month"`. Use custom `format` and `parse` functions to handle month/year input format. :component-preview{component="date-picker" name="month-picker"} ### Year Picker Create a year-only picker by setting `defaultView="year"` and `minView="year"`. Use custom `format` and `parse` functions to handle year-only input format. :component-preview{component="date-picker" name="year-picker"} ### Inline Use the `inline` prop to display the date picker directly on the page, without a popup. > When using the `inline` prop, omit the `Portal`, `Positioner`, and `Content` components to render the calendar inline > within your layout. :component-preview{component="date-picker" name="inline"} ### Custom Parsing Use the `parse` prop to implement custom date parsing logic. This allows users to enter dates in flexible formats like "25/12" or "25/12/24" which are automatically converted to valid dates. :component-preview{component="date-picker" name="custom-parsing"} ### Month Picker Range Create a month range picker by combining `selectionMode="range"` with `defaultView="month"` and `minView="month"`. This is useful for selecting billing periods or date ranges by month. :component-preview{component="date-picker" name="month-picker-range"} ### Year Range Create a year range picker by combining `selectionMode="range"` with `defaultView="year"` and `minView="year"`. This is useful for selecting multi-year periods. :component-preview{component="date-picker" name="year-range"} ### Select Today Use the `selectToday` method from the date picker context to add a "Today" button that quickly selects the current date. :component-preview{component="date-picker" name="select-today"} ### Fixed Weeks Use the `fixedWeeks` prop to always display 6 weeks in the calendar, preventing layout shifts when navigating between months. :component-preview{component="date-picker" name="fixed-weeks"} ### Form Use the `name` prop to integrate the date picker with native HTML forms. The selected date value will be submitted as form data. This example also uses `isDateUnavailable` to disable weekends. :component-preview{component="date-picker" name="form"} ### With Time Integrate a time input with the date picker using `CalendarDateTime` from `@internationalized/date`. The time input updates the hour and minute of the selected date value. :component-preview{component="date-picker" name="with-time"} ## API See [Ark UI Date Picker docs](https://ark-ui.com/vue/docs/components/date-picker){rel=""nofollow""} for full props and examples. # Dialog :component-preview{component="dialog" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/dialog.json --- :: ## Usage ```vue ``` ## Composition ```text Dialog.Root ├── Dialog.Body ├── Dialog.Actions ├── Dialog.CloseTrigger ├── Dialog.Content ├── Dialog.Context ├── Dialog.Description ├── Dialog.RootProvider ├── Dialog.ScrollContainer ├── Dialog.ScrollSection ├── Dialog.Title ├── Dialog.Trigger ``` ## Examples ### Controlled Manage the dialog state using the `open` and `onOpenChange` props. :component-preview{component="dialog" name="controlled"} ### Root Provider An alternative way to control the dialog is to use the `RootProvider` component and the `useDialog` hook. This way you can access the state and methods from outside the component. :component-preview{component="dialog" name="root-provider"} ### Alert Dialog For critical confirmations or destructive actions, use `role="alertdialog"`. Alert dialogs differ from regular dialogs in important ways: - **Automatic focus**: The close/cancel button receives focus when opened, prioritizing the safest action - **Requires explicit dismissal**: Cannot be closed by clicking outside, only via button clicks or Escape key :component-preview{component="dialog" name="alert-dialog"} ### Lazy Mount Use `lazyMount` to render dialog content only when first opened. Combine with `unmountOnExit` to unmount when closed, freeing up resources. Prefer this over conditionally rendering `Dialog.Root`—see **Conditional Rendering** in the [Ark UI docs](https://ark-ui.com/vue/docs/components/dialog){rel=""nofollow""}. :component-preview{component="dialog" name="lazy-mount"} ### Initial Focus Use `initialFocusEl` to control which element receives focus when the dialog opens. :component-preview{component="dialog" name="initial-focus"} ### Final Focus Use `finalFocusEl` to control which element receives focus when the dialog closes. Defaults to the trigger element. :component-preview{component="dialog" name="final-focus"} ### Non-Modal Use `modal={false}` to allow interaction with elements outside the dialog. Disables focus trapping and scroll prevention. :component-preview{component="dialog" name="non-modal"} ### Inside Scroll Make the content area scrollable while keeping header and footer fixed using `maxHeight` and `overflow: auto`. :component-preview{component="dialog" name="inside-scroll"} ### Outside Scroll Make the positioner scrollable so the dialog can extend beyond the viewport. :component-preview{component="dialog" name="outside-scroll"} ### Context Access the dialog's state and methods with `Dialog.Context` or the `useDialogContext` hook. :component-preview{component="dialog" name="context"} ### Open from Menu Open a dialog imperatively from a menu item using the `onClick` handler. :component-preview{component="dialog" name="open-from-menu"} ### Nested Nest dialogs within one another. The parent receives `data-has-nested` and `--nested-layer-count` CSS variable for styling effects like zoom-out. :component-preview{component="dialog" name="nested"} ### Multiple Triggers Share a single dialog across multiple trigger elements. Pass a `value` to each `Dialog.Trigger` and use `onTriggerValueChange` to update the dialog content based on which trigger was clicked. :component-preview{component="dialog" name="multiple-triggers"} ### Confirmation Intercept close attempts to show confirmation prompts, preventing data loss from unsaved changes. :component-preview{component="dialog" name="confirmation"} ## API See [Ark UI Dialog docs](https://ark-ui.com/vue/docs/components/dialog){rel=""nofollow""} for full props and examples. # DialogCaller :component-preview{component="dialog-caller" name="basic"} ## Features - **Programmatic API** — Register a component once with `useDialogCaller()`, then `await caller.call(props)` from any handler - **Promise-based results** — Components finish calls with `call.resolve()` or `call.reject()`; the outer promise always resolves (shape configurable) - **Stack support** — Nested and concurrent dialogs mount as separate stack entries with automatic z-index layering - **Optional dialog shell** — `DialogCaller.DialogShell` wires open state and external dismiss for Ark UI dialogs ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/dialog-caller.json --- :: ## Setup Mount the host once in your app root: ```vue ``` ## Usage Register a dialog component once, then call it imperatively: ```vue ``` Inside the called component, use `useDialogCallerContext()` and assign it to `call`: ```vue ``` ## Composition ```text DialogCaller.Host └── (dynamic stack entries) DialogCaller.Provider └── custom host wiring via useDialogCallerHost() DialogCaller.DialogShell └── Dialog.Content └── your dialog UI ``` ## Examples ### Delete confirmation Use a single `useDialogCaller` registration for the whole table — no dialog duplicated per row: :component-preview{component="dialog-caller" name="basic"} ### Nested dialogs Edit the form, then cancel with unsaved changes. The confirmation dialog stacks on top while the form stays mounted: :component-preview{component="dialog-caller" name="nested"} ## API ### `useDialogCaller(component, options?)` Returns `{ call(props), reject() }`. | Option | Type | Default | Description | | -------------------- | ------------------------------ | -------------- | ------------------------------------------------------------------------------- | | `id` | `string` | component name | Registry key for idempotent registration | | `exitDuration` | `number` | `200` | Milliseconds to keep the instance mounted after resolve/reject (exit animation) | | `resultShape` | `"cancelled" | "data" | "raw"` | `"cancelled"` | Shape of the value returned by `call()` | | `defaultRejectValue` | `unknown` | `null` | Value returned on reject when `resultShape` is `"raw"` | ### `useDialogCallerContext()` Returns `{ props, phase, resolve, reject, id }`. Assign to `call` and use `call.resolve()` / `call.reject()` without destructuring. ### Result shapes | `resultShape` | After `call.resolve(data)` | After `call.reject(reason?)` | | ------------- | ------------------------------------------ | ------------------------------------------ | | `"cancelled"` | `{ cancelled: false, data, reason: null }` | `{ cancelled: true, data: null, reason? }` | | `"data"` | `{ data }` | `{ data: null }` | | `"raw"` | `data` | `defaultRejectValue` | ## Notes - Each `call()` mounts a new stack entry. For HTTP-heavy dialogs, fetch data from props (e.g. with `watch`) rather than in `onMounted`. - `DialogCaller.Host` must be mounted before calling `call()` — otherwise an error is thrown. # Drawer :component-preview{component="drawer" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/drawer.json --- :: ## Usage ```vue ``` ## Composition ```text Drawer.Root ├── Drawer.CloseTrigger ├── Drawer.Content ├── Drawer.Description ├── Drawer.Context ├── Drawer.Grabber ├── Drawer.GrabberIndicator ├── Drawer.Indent ├── Drawer.IndentBackground ├── Drawer.RootProvider ├── Drawer.Stack ├── Drawer.SwipeArea ├── Drawer.Title ├── Drawer.Trigger ``` ## Examples ### Swipe Direction Use the `swipeDirection` prop to control which edge the drawer slides in from. :component-preview{component="drawer" name="swipe-direction"} ### Snap Points Use the `snapPoints` prop to define intermediate positions the drawer can snap to. :component-preview{component="drawer" name="snap-points"} ### Modal Set `modal` to `false` to allow interaction with the rest of the page while the drawer is open. :component-preview{component="drawer" name="modal"} ### Controlled Use the `open` and `onOpenChange` props to control the drawer state. :component-preview{component="drawer" name="controlled"} ### Scrollable :component-preview{component="drawer" name="scrollable"} ### No Drag Area Apply the `data-no-drag` attribute to any element inside the drawer to prevent dragging from starting on it. :component-preview{component="drawer" name="no-drag-area"} ### Non Draggable Set `draggable` to `false` to disable drag-to-dismiss entirely. :component-preview{component="drawer" name="non-draggable"} ### Indent Background Use `Drawer.IndentBackground` to create a visual indent effect on the page behind the drawer. :component-preview{component="drawer" name="indent-background"} ### Multiple Triggers Use the `value` prop on `Drawer.Trigger` to share a single drawer across multiple trigger elements. The `onTriggerValueChange` callback fires when a different trigger is activated. :component-preview{component="drawer" name="multiple-triggers"} ### Using the Root Provider Use the `useDrawer` hook and `Drawer.RootProvider` to control the drawer from outside the component tree. :component-preview{component="drawer" name="root-provider"} ## API See [Ark UI Drawer docs](https://ark-ui.com/vue/docs/components/drawer){rel=""nofollow""} for full props and examples. # Editable :component-preview{component="editable" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/editable.json --- :: ## Usage Wrap `Editable` in `Field` and use `Field.Label` instead of a dedicated editable label. ```vue ``` ## Examples ### Controlled Use the `value` and `onValueChange` props to control the editable state. :component-preview{component="editable" name="controlled"} ### Root Provider An alternative way to control the editable is to use the `RootProvider` component and the `useEditable` hook. This way you can access the state and methods from outside the component. :component-preview{component="editable" name="root-provider"} ### Context Access the editable's state with `Editable.Context` or the `useEditableContext` hook—great for showing keyboard hints when editing. :component-preview{component="editable" name="context"} ### Controls In some cases, you might need to use custom controls to toggle the edit and read mode. We use the render prop pattern to provide access to the internal state of the component. :component-preview{component="editable" name="controls"} ### Textarea Use the `asChild` prop on `Editable.Input` to render a textarea for multi-line editing. :component-preview{component="editable" name="textarea"} ### Field The `Field` component helps manage form-related state and accessibility attributes of an editable. It includes handling ARIA labels, helper text, and error text to ensure proper accessibility. :component-preview{component="editable" name="field"} ## Composition ```text Field.Root ├── Field.Label ├── Editable.Root │ ├── Editable.Area │ │ ├── Editable.Input │ │ └── Editable.Preview │ ├── Editable.Control │ │ ├── Editable.EditTrigger │ │ ├── Editable.SubmitTrigger │ │ └── Editable.CancelTrigger │ └── Editable.Context └── Field.HelperText / Field.ErrorText ``` ## API See [Ark UI Editable docs](https://ark-ui.com/vue/docs/components/editable){rel=""nofollow""} for full props and examples. # Empty :component-preview{component="empty" name="basic"} ## Features - **Composable** — Flexible slot-based layout with `Empty.Header`, `Empty.Media`, `Empty.Title`, `Empty.Description`, and `Empty.Content` - **Styled primitives** — Opinionated defaults for spacing, typography, and icon media - **Customizable** — Override any part with the `class` prop ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/empty.json --- :: ## Usage ```vue ``` ## Composition ```text Empty.Root ├── Empty.Header │ ├── Empty.Media │ ├── Empty.Title │ └── Empty.Description └── Empty.Content ``` ## Examples ### Outline Use the `border` utility class to create an outline empty state. :component-preview{component="empty" name="outline"} ### Background Use the `bg-*` utilities to add a background to the empty state. :component-preview{component="empty" name="muted"} ### Avatar Use `Empty.Media` to display an avatar in the empty state. :component-preview{component="empty" name="avatar"} ### Avatar Group Use `Empty.Media` to display an avatar group in the empty state. :component-preview{component="empty" name="avatar-group"} ### Input Group Add an `InputGroup` component to `Empty.Content`. :component-preview{component="empty" name="input-group"} ## API ### Empty.Media | Prop | Type | Default | Description | | --------- | -------------------- | ----------- | ----------------------------------- | | `variant` | `"default" | "icon"` | `"default"` | Visual style of the media container | | `class` | `string` | — | Additional CSS classes | # Field :component-preview{component="field" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/field.json --- :: ## Usage ```vue ``` ## Examples The `Field` component provides contexts such as `invalid`, `disabled`, `required`, and `readOnly` for form elements. While most Ark UI components natively support these contexts, you can also use the `Field` component with standard HTML form elements. ### Input This example shows how to use the `Field` component with a standard input field. :component-preview{component="field" name="basic"} ### Textarea This example illustrates how to use the `Field` component with a textarea element. :component-preview{component="field" name="textarea"} ### Textarea Autoresize Pass the `autoresize` prop to the `Textarea` component to enable automatic resizing as the user types. :component-preview{component="field" name="textarea-autoresize"} ### Select This example demonstrates how to integrate the `Field` component with a select dropdown. :component-preview{component="field" name="select"} ### Root Provider An alternative way to control the field is to use the `RootProvider` component and the `useField` hook. This way you can access the state and methods from outside the component. :component-preview{component="field" name="root-provider"} ### Custom Control Use the `Field.Context` or `useFieldContext` hook to access the internal state of the field. This can help you wire up custom controls with the `Field` component. :component-preview{component="field" name="custom-control"} ## Composition ```text Field.Root ├── Field.Context ├── Field.ErrorText ├── Field.HelperText ├── Field.Input ├── Field.Item ├── Field.Label ├── Field.RequiredIndicator ├── Field.RootProvider ├── Field.Select ├── Field.Textarea ``` ## API See [Ark UI Field docs](https://ark-ui.com/vue/docs/components/field){rel=""nofollow""} for full props and examples. # Fieldset :component-preview{component="fieldset" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/fieldset.json --- :: ## Usage ```vue ``` ## Composition ```text Fieldset.Root ├── Fieldset.Context ├── Fieldset.ErrorText ├── Fieldset.HelperText ├── Fieldset.Legend ├── Fieldset.RootProvider ``` ## Examples The `Fieldset` component provides contexts such as `invalid` and `disabled` for form elements. While most Ark UI components natively support these contexts, you can also use the `Field` component with standard HTML form elements. ### Field This example demonstrates how to use the `Field` component with a standard input field within a `Fieldset`. :component-preview{component="fieldset" name="field"} ### Checkbox This example shows how to use the `Fieldset` component with other Ark UI form elements like `Checkbox`. :component-preview{component="fieldset" name="checkbox"} ### Root Provider An alternative way to control the fieldset is to use the `RootProvider` component and the `useFieldset` hook. This way you can access the state and methods from outside the component. :component-preview{component="fieldset" name="root-provider"} ### Input with Select This example shows how to use the `Fieldset` component with `Field.Input` and `Select` to create a interactive phone input component. :component-preview{component="fieldset" name="input-with-select"} ## API See [Ark UI Fieldset docs](https://ark-ui.com/vue/docs/components/fieldset){rel=""nofollow""} for full props and examples. # File Upload :component-preview{component="file-upload" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/file-upload.json --- :: ## Usage ```vue ``` ## Composition ```text FileUpload.Root ├── FileUpload.Label ├── FileUpload.Dropzone │ └── FileUpload.Trigger ├── FileUpload.ItemGroup │ └── FileUpload.Item │ ├── FileUpload.ItemPreview │ │ └── FileUpload.ItemPreviewImage │ ├── FileUpload.ItemName │ ├── FileUpload.ItemSizeText │ └── FileUpload.ItemDeleteTrigger ├── FileUpload.ClearTrigger ├── FileUpload.HiddenInput ├── FileUpload.Context └── FileUpload.RootProvider ``` ## Examples ### Initial Files Use the `defaultAcceptedFiles` prop to set the initial files in the file upload component. :component-preview{component="file-upload" name="initial-files"} ### Clear Trigger Use the `ClearTrigger` to remove all uploaded files at once. :component-preview{component="file-upload" name="clear-trigger"} ### Dropzone Use the `Dropzone` to enable drag-and-drop. It exposes a `data-dragging` attribute for styling. :component-preview{component="file-upload" name="dropzone"} ### Directory Upload Use the `directory` prop to upload entire folders. Access file paths through `file.webkitRelativePath`. :component-preview{component="file-upload" name="directory-upload"} > When uploading directories with many files, set `maxFiles` to a higher value or remove it entirely to prevent rejections. ### Accepted File Types Use the `accept` prop to restrict file types. Accepts MIME types (`image/png`) or extensions (`.pdf`). :component-preview{component="file-upload" name="accepted-file-types"} ### Error Handling Set constraints with `maxFiles`, `maxFileSize`, `minFileSize`, and `accept`. Rejected files include error codes like `TOO_MANY_FILES`, `FILE_INVALID_TYPE`, `FILE_TOO_LARGE`, or `FILE_EXISTS`. :component-preview{component="file-upload" name="error-handling"} ### File Transformations Use `transformFiles` to process files before they're added. Useful for image compression, format conversion, or resizing. :component-preview{component="file-upload" name="file-transformations"} ### Field Use `Field` to add helper text and error handling. :component-preview{component="file-upload" name="field"} ### Root Provider An alternative way to control the file upload is to use the `RootProvider` component and the `useFileUpload` hook. This way you can access the state and methods from outside the component. :component-preview{component="file-upload" name="root-provider"} ### Pasting Files Use `setClipboardFiles` to enable pasting images from the clipboard. :component-preview{component="file-upload" name="pasting-files"} ### Media Capture Use `capture` to access the device camera. Set to `"environment"` for back camera or `"user"` for front camera. :component-preview{component="file-upload" name="media-capture"} ### Rejected Files Access `rejectedFiles` from the context to display validation errors. :component-preview{component="file-upload" name="rejected-files"} ## API See [Ark UI File Upload docs](https://ark-ui.com/vue/docs/components/file-upload){rel=""nofollow""} for full props and examples. # Filters :component-preview{component="filters" name="basic"} ## Features - Typed field factories. - Text, number, date, boolean, select, and multi-select values. - Long or short filter chips. - Groups and nested menus. - `outline` and `secondary` variants. - `sm`, `md`, and `lg` sizes. ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/filters.json --- :: ## Usage ```vue ``` ## Composition Use the following composition to build a Filters setup: ```text Filters.Provider ├── Filters.Menu │ ├── Filters.MenuTrigger │ └── Filters.MenuContent ├── Filters.Group │ └── Filters.Item └── Filters.Clear ``` ## Examples ### Sizes and variants Set `variant` and `size` on `Filters.Provider`, use `filter-style="short"` on `Filters.Group` to show only values. :component-preview{component="filters" name="short"} ### Custom menu trigger Provide a custom trigger via the `Filters.MenuTrigger` slot. :component-preview{component="filters" name="custom-menu"} ## API Reference ### Components | Component | Use | | --------------------- | --------------------------------- | | `Filters.Provider` | Root state and context. | | `Filters.Menu` | Add-filter dropdown. | | `Filters.MenuTrigger` | Default trigger, or custom slot. | | `Filters.MenuContent` | Field list, groups, and submenus. | | `Filters.Group` | Chip wrapper. | | `Filters.Item` | One filter chip. | | `Filters.Clear` | Clears all filters. | ### Filters.Provider | Prop | Type | Default | | --------- | ------------------------- | ----------- | | `filters` | `Filter[]` | `[]` | | `fields` | `FilterFieldItem[]` | - | | `variant` | `"outline" | "secondary"` | `"outline"` | | `size` | `"sm" | "md" | "lg"` | `"md"` | ### Filters.Group | Prop | Type | Default | | ------------- | ------------------ | -------- | | `filterStyle` | `"long" | "short"` | `"long"` | ### Fields Build fields with `Field.*`. | Helper | Extra options | | -------------------- | ------------------------------------ | | `Field.TextField` | `minLength`, `maxLength` | | `Field.NumberField` | `min`, `max`, `step`, `numberFormat` | | `Field.DateField` | `min`, `max` | | `Field.BooleanField` | `trueValue`, `falseValue` | | `Field.Group` | `label`, `fields` | | `Field.Submenu` | `label`, `icon`, `fields` | Common field options: `key`, `label`, `icon`, `operators`. ```ts const fields = [ Field.TextField({ key: "name", label: "Name", operators: [ Operator.Contain({ label: "contains" }) ], }), ]; ``` ### Operators Build operators with `Operator.*`. | Helper | Value | Input | | --------------------- | -------------- | ------------------- | | `Operator.Eq` | `eq` | `input` or `select` | | `Operator.Neq` | `neq` | `input` or `select` | | `Operator.Contain` | `contains` | `input` | | `Operator.NotContain` | `not_contains` | `input` | | `Operator.In` | `in` | `multi-select` | | `Operator.Nin` | `nin` | `multi-select` | | `Operator.Btw` | `btw` | `range` | | `Operator.Null` | `is_null` | `none` | | `Operator.NotNull` | `not_null` | `none` | | `Operator.Gt` | `gt` | `input` | | `Operator.Lt` | `lt` | `input` | Common operator options: `label`, `default`, `defaultValue`, `options`. ```ts Operator.In({ label: "any of", options: { items: [ { label: "Active", value: "active" }, { label: "Pending", value: "pending" }, ], }, }); ``` ### Filter Active filters are plain objects. ```ts const filters: Filter[] = [ { field: "status", operator: "in", value: ["active", "pending"] }, { field: "price", operator: "btw", value: [100, 500] }, ]; ``` `FilterValue` can be `string`, `string[]`, `number`, `number[]`, `boolean`, `CalendarDate`, `CalendarDate[]`, `{ start, end }`, or `null`. # Floating Panel :component-preview{component="floating-panel" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/floating-panel.json --- :: ## Usage ```vue ``` ## Composition ```text FloatingPanel.Root ├── FloatingPanel.Body ├── FloatingPanel.CloseTrigger ├── FloatingPanel.Content ├── FloatingPanel.Context ├── FloatingPanel.DragTrigger ├── FloatingPanel.Header ├── FloatingPanel.Positioner ├── FloatingPanel.ResizeTrigger ├── FloatingPanel.StageTrigger ├── FloatingPanel.RootProvider ├── FloatingPanel.Title ├── FloatingPanel.Trigger ├── FloatingPanel.Control ``` ## Examples ### Controlled size To control the size of the floating panel programmatically, you can pass the `size` `onResize` prop to the machine. :component-preview{component="floating-panel" name="controlled-size"} ### Controlled position To control the position of the floating panel programmatically, you can pass the `position` and `onPositionChange` prop to the machine. :component-preview{component="floating-panel" name="controlled-position"} ### Anchor Position Use the `getAnchorPosition` function to compute the initial position of the floating panel. This function is called when the panel is opened and receives the `triggerRect` and `boundaryRect`. :component-preview{component="floating-panel" name="anchor-position"} ### Open State To control the open state of the floating panel programmatically, you can pass the `open` and `onOpenChange` prop to the machine. :component-preview{component="floating-panel" name="open-state"} ### Lazy Mount To lazy mount the floating panel, you can pass the `lazyMount` prop to the machine. :component-preview{component="floating-panel" name="lazy-mount"} ### Context To access the context of the floating panel, you can use the `useFloatingPanelContext` hook or the `FloatingPanel.Context` component. :component-preview{component="floating-panel" name="context"} ## API See [Ark UI Floating Panel docs](https://ark-ui.com/vue/docs/components/floating-panel){rel=""nofollow""} for full props and examples. # Hover Card :component-preview{component="hover-card" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/hover-card.json --- :: ## Usage ```vue ``` ## Composition ```text HoverCard.Root ├── HoverCard.ArrowTip ├── HoverCard.Arrow ├── HoverCard.Content ├── HoverCard.Context ├── HoverCard.Positioner ├── HoverCard.RootProvider ├── HoverCard.Trigger ``` ## Examples ### Controlled The controlled `HoverCard` component provides an interface for managing the state of the hover card using the `open` and `onOpenChange` props: :component-preview{component="hover-card" name="controlled"} ### Root Provider An alternative way to control the hover card is to use the `RootProvider` component and the `useHoverCard` hook. This way you can access the state and methods from outside the component. :component-preview{component="hover-card" name="root-provider"} ### Delay Control the open and close delay of the hover card using the `openDelay` and `closeDelay` props: :component-preview{component="hover-card" name="delay"} ### Positioning The `HoverCard` component can be customized in its placement and distance from the trigger element through the `positioning` prop: :component-preview{component="hover-card" name="positioning"} ### Context Access the hover card's state with `HoverCard.Context` or the `useHoverCardContext` hook: :component-preview{component="hover-card" name="context"} ### Multiple Triggers Share a single hover card across multiple trigger elements. Pass a `value` to each `HoverCard.Trigger` — the card repositions to the active trigger without closing. :component-preview{component="hover-card" name="multiple-triggers"} ## API See [Ark UI Hover Card docs](https://ark-ui.com/vue/docs/components/hover-card){rel=""nofollow""} for full props and examples. # Image :component-preview{component="image" name="basic"} ## Features - **Loading states** — Automatic detection of loading, error, and success states - **Fallback support** — Display placeholder content during loading or on error - **Composable** — Flexible slot-based architecture with `Image.Source`, `Image.Loading`, `Image.Error`, and `Image.Fallback` - **Zag-powered** — State machine API via `useImage` and `Image.Provider` ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/image.json --- :: ## Usage ```vue ``` ## Composition ```text Image.Root ├── Image.Source ├── Image.Loading ├── Image.Error └── Image.Fallback ``` ## Examples ### Fallback Use `Image.Fallback` to display a placeholder while the image is loading or when it fails to load. :component-preview{component="image" name="fallback"} ### Loading Use `Image.Loading` to show a dedicated loading indicator. :component-preview{component="image" name="loading"} ### Controlled For a controlled image, manage the state with `v-model:state`. When controlled, image load and error events no longer update the state automatically — use `setState` from `useImage` or bind the model yourself. :component-preview{component="image" name="controlled"} ## API Built with a custom Zag.js state machine. Use `useImage()` with `Image.Provider` for imperative control (`api.value.setState(...)`, `api.value.state`). Polymorphic parts use Ark UI `ark` / `as-child`. # Image Cropper :component-preview{component="image-cropper" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/image-cropper.json --- :: ## Usage ```vue ``` ## Composition ```text ImageCropper.Root ├── ImageCropper.Context ├── ImageCropper.Grid ├── ImageCropper.Handle ├── ImageCropper.Image ├── ImageCropper.RootProvider ├── ImageCropper.Selection └── ImageCropper.Viewport ``` ## Examples ### Aspect Ratio Lock the crop area to a specific aspect ratio. Use the `aspectRatio` prop—pass a number like `16/9` for widescreen or `1` for square. :component-preview{component="image-cropper" name="aspect-ratio"} ### Circle Crop Use `cropShape="circle"` for profile pictures or avatars. The selection becomes a circle instead of a rectangle. :component-preview{component="image-cropper" name="circle-crop"} ### Initial Crop Start with a pre-defined crop area using the `initialCrop` prop. Pass an object with `x`, `y`, `width`, and `height` in pixels. :component-preview{component="image-cropper" name="initial-crop"} ### Controlled Zoom Control zoom programmatically with the `zoom` and `onZoomChange` props. Useful when you want external buttons to zoom in and out. :component-preview{component="image-cropper" name="controlled-zoom"} ### Zoom Limits Set `minZoom` and `maxZoom` to constrain how far users can zoom. Prevents over-zooming or zooming out past the image bounds. :component-preview{component="image-cropper" name="zoom-limits"} ### Rotation Rotate the image with the `rotation` and `onRotationChange` props. Values are in degrees—common increments are 90 or 180. :component-preview{component="image-cropper" name="rotation"} ### Flip Flip the image horizontally or vertically using the `flip` prop. Pass an object with `horizontal` and `vertical` booleans. :component-preview{component="image-cropper" name="flip"} ### Min and Max Size Constrain the crop area size with `minWidth`, `minHeight`, `maxWidth`, and `maxHeight`. Keeps the selection within sensible bounds. :component-preview{component="image-cropper" name="min-and-max-size"} ### Fixed Crop Area Set `fixedCropArea` to `true` when the crop area should stay fixed while the image moves underneath. Useful for overlay-style cropping. :component-preview{component="image-cropper" name="fixed-crop-area"} ### Crop Preview Use `getCroppedImage()` from the context to get the cropped result. Call it with `{ output: 'dataUrl' }` for a base64 string you can use in an `img` src. :component-preview{component="image-cropper" name="crop-preview"} ### Reset The context exposes a `reset()` method that restores the image to its initial state. Handy for an "undo" or "start over" button. :component-preview{component="image-cropper" name="reset"} ### Events Listen to `onCropChange` and `onZoomChange` to track crop position and zoom level. Use these to sync with external state or show live previews. :component-preview{component="image-cropper" name="events"} ### Context Use `ImageCropper.Context` to access the cropper API from anywhere inside the root. You get methods like `zoomBy`, `rotateBy`, and `setZoom`. :component-preview{component="image-cropper" name="context"} ### Root Provider Use `RootProvider` with `useImageCropper` when you need to control the cropper from outside the component tree. Build custom toolbars or integrate with form state. :component-preview{component="image-cropper" name="root-provider"} ## API See [Ark UI Image Cropper docs](https://ark-ui.com/vue/docs/components/image-cropper){rel=""nofollow""} for full props and examples. # Input :component-preview{component="input" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/input.json --- :: ## Usage ```vue ``` ## Examples ### Sizes Use the `size` prop to change the height of the input. :component-preview{component="input" name="sizes"} ### Field Combine the `Input` component with `Field` to add a label, helper text, and validation context. :component-preview{component="input" name="field"} See [Ark UI Field docs](https://ark-ui.com/vue/docs/components/field){rel=""nofollow""} for field composition patterns. # Input Group :component-preview{component="input-group" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/input-group.json --- :: ## Usage ```vue ``` ## Composition ```text InputGroup.Root ├── InputGroup.Input or InputGroup.Textarea ├── InputGroup.Addon ├── InputGroup.Button └── InputGroup.Text ``` For proper focus management, `InputGroupAddon` should always be placed after `InputGroupInput` or `InputGroupTextarea` in the DOM. Use the `align` prop to visually position the addon. ## Examples ### Icon Add icons inside `InputGroupAddon` to decorate the input. :component-preview{component="input-group" name="icon"} ### Text Use `InputGroupText` for inline prefixes, suffixes, and helper labels. :component-preview{component="input-group" name="text"} ### Button Add action buttons with `InputGroupButton` inside an addon. :component-preview{component="input-group" name="button"} ### Tooltip Wrap `InputGroupButton` with `Tooltip.Trigger` and `as-child` to add contextual help on hover. :component-preview{component="input-group" name="tooltip"} ### Menu Use `Menu.Trigger` with `as-child` on `InputGroupButton` to attach a dropdown menu to the input. :component-preview{component="input-group" name="menu"} ## Align Use the `align` prop on `InputGroupAddon` to position the addon relative to the input: | Value | Description | | -------------- | ---------------------------- | | `inline-start` | Start of the input (default) | | `inline-end` | End of the input | | `block-start` | Above the input | | `block-end` | Below the input | Works with both `InputGroupInput` and `InputGroupTextarea`. # Json Tree View :component-preview{component="json-tree-view" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/json-tree-view.json --- :: ## Usage ```vue ``` ## Composition ```text JsonTreeView.Root ├── JsonTreeView.RootProvider └── JsonTreeView.Tree ``` ## Examples ### Different Data Types The JSON tree view can display various JavaScript data types including objects, arrays, primitives, and special values: :component-preview{component="json-tree-view" name="array-data"} ### Functions and Methods Display JavaScript functions, async functions, and generators in your JSON tree: :component-preview{component="json-tree-view" name="functions"} ### Regular Expressions Regular expressions are displayed with their pattern and flags: :component-preview{component="json-tree-view" name="regex"} ### Error Objects Error objects and their stack traces can be visualized: :component-preview{component="json-tree-view" name="errors"} ### Map and Set Objects Native JavaScript Map and Set objects are supported: :component-preview{component="json-tree-view" name="map-and-set"} ### Controlling Expand Level Use the `defaultExpandedDepth` prop to control how many levels are expanded by default: :component-preview{component="json-tree-view" name="expand-level"} ### Custom Value Rendering You can customize how specific values are rendered using the `renderValue` prop. This example shows how to make email addresses clickable: :component-preview{component="json-tree-view" name="render-value"} ### Configuration Options The JSON tree view supports several configuration options to customize the display: ```vue ``` **Configuration Options:** - **`quotesOnKeys`**: Whether to show quotes around object keys - **`showNonenumerable`**: Whether to show non-enumerable properties - **`maxPreviewItems`**: Maximum number of items to show in object/array previews - **`collapseStringsAfterLength`**: Collapse strings longer than this length - **`groupArraysAfterLength`**: Group array items when array is longer than this length ### Using the Root Provider The `RootProvider` component provides a context for the JSON tree view. It accepts the value of the `useJsonTreeView` hook. You can leverage it to access the component state and methods from outside the JSON tree view. :component-preview{component="json-tree-view" name="root-provider"} > If you're using the `RootProvider` component, you don't need to use the `Root` component. ## API See [Ark UI Json Tree View docs](https://ark-ui.com/vue/docs/utilities/json-tree-view){rel=""nofollow""} for full props and examples. # Kbd :component-preview{component="kbd" name="basic"} ## Features - **Semantic** — Renders as a native `kbd` element - **Composable** — Pair `Kbd.Item` with `Kbd.Group` for key combinations - **Context-aware** — Adapts contrast when used inside tooltip content - **Customizable** — Override styles with the `class` prop ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/kbd.json --- :: ## Usage ```vue ``` ## Composition ```text Kbd.Item Kbd.Group ├── Kbd.Item └── Kbd.Item ``` ## Examples ### Group Use `Kbd.Group` to group keyboard keys together. :component-preview{component="kbd" name="group"} ### Button Use `Kbd.Item` inside a `Button` to show a keyboard shortcut. :component-preview{component="kbd" name="button"} ### Tooltip Use `Kbd.Item` inside a `Tooltip` to show a keyboard shortcut on hover. :component-preview{component="kbd" name="tooltip"} ### Input Group Use `Kbd.Item` inside an `InputGroup.Addon` to hint at a keyboard shortcut. :component-preview{component="kbd" name="input-group"} ## API ### Kbd.Item | Prop | Type | Default | Description | | ------- | -------- | ------- | ---------------------- | | `class` | `string` | — | Additional CSS classes | ### Kbd.Group | Prop | Type | Default | Description | | ------- | -------- | ------- | ---------------------- | | `class` | `string` | — | Additional CSS classes | # Listbox :component-preview{component="listbox" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/listbox.json --- :: ## Usage ```vue ``` ## Examples ### Controlled The Listbox component can be controlled by using the `value` and `onValueChange` props. This allows you to manage the selected value externally. :component-preview{component="listbox" name="controlled"} ### Root Provider An alternative way to control the listbox is to use the `RootProvider` component and the `useListbox` hook. This way you can access the state and methods from outside the component. :component-preview{component="listbox" name="root-provider"} ### Disabled Item Listbox items can be disabled using the `disabled` prop on the collection item. :component-preview{component="listbox" name="disabled-item"} ### Multiple You can set the `selectionMode` property as `multiple` to allow the user to select multiple items at a time. :component-preview{component="listbox" name="multiple"} ### Grouping The Listbox component supports grouping items. You can use the `groupBy` function to group items based on a specific property. :component-preview{component="listbox" name="grouping"} ### Extended Selection The extended selection mode allows users to select multiple items using keyboard modifiers like `Cmd` (Mac) or `Ctrl` (Windows/Linux). :component-preview{component="listbox" name="extended-selection"} ### Horizontal Use the `orientation` prop to display the listbox items horizontally. :component-preview{component="listbox" name="horizontal"} ### Grid Layout Use `createGridCollection` to display items in a grid layout with keyboard navigation support. :component-preview{component="listbox" name="grid-layout"} ### Filtering Use `useListCollection` with the `filter` function to enable filtering of items. :component-preview{component="listbox" name="filtering"} ### Select All Use `useListboxContext` to implement a "Select All" functionality that allows users to select or deselect all items at once. :component-preview{component="listbox" name="select-all"} ### Value Text Use `Listbox.ValueText` to display the selected values as a comma-separated string. :component-preview{component="listbox" name="value-text"} ## Composition ```text Listbox.Root ├── Listbox.Context ├── Listbox.Content ├── Listbox.Empty ├── Listbox.Input ├── Listbox.Item ├── Listbox.ItemContext ├── Listbox.ItemGroup ├── Listbox.ItemGroupLabel ├── Listbox.ItemIndicator ├── Listbox.ItemText ├── Listbox.Label ├── Listbox.RootProvider ├── Listbox.ValueText ``` ## API See [Ark UI Listbox docs](https://ark-ui.com/vue/docs/components/listbox){rel=""nofollow""} for full props and examples. # Marquee :component-preview{component="marquee" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/marquee.json --- :: ## Usage ```vue ``` ## Composition ```text Marquee.Root ├── Marquee.Edge ├── Marquee.Viewport │ └── Marquee.Content │ └── Marquee.Item ├── Marquee.Context └── Marquee.RootProvider ``` ## Examples ### Auto Fill Use the `autoFill` prop to automatically duplicate content to fill the viewport. The `spacing` prop controls the gap between duplicated content instances: :component-preview{component="marquee" name="auto-fill"} ### Reverse Set the `reverse` prop to reverse the scroll direction: :component-preview{component="marquee" name="reverse"} ### Vertical Set `side="bottom"` (or `side="top"`) to create a vertical marquee: :component-preview{component="marquee" name="vertical"} ### Speed Control the animation speed using the `speed` prop, which accepts values in pixels per second: :component-preview{component="marquee" name="speed"} ### Pause on Interaction Enable `pauseOnInteraction` to pause the marquee when users hover or focus on it, improving accessibility: :component-preview{component="marquee" name="pause-on-interaction"} ### Programmatic Control Use the `useMarquee` hook with `Marquee.RootProvider` to access the marquee API and control playback programmatically: :component-preview{component="marquee" name="programmatic-control"} > If you're using the `Marquee.RootProvider` component, you don't need to use the `Marquee.Root` component. ### Loops Set the `loopCount` prop to run the marquee a specific number of times. Use `onLoopComplete` to track each loop iteration and `onComplete` to know when all loops finish: :component-preview{component="marquee" name="finite-loops"} ### Edges Add `Marquee.Edge` components to create fade effects at the start and end of the scrolling area: :component-preview{component="marquee" name="with-edges"} ## API See [Ark UI Marquee docs](https://ark-ui.com/vue/docs/components/marquee){rel=""nofollow""} for full props and examples. # Menu :component-preview{component="menu" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/menu.json --- :: ## Usage ```vue ``` ## Composition ```text Menu.Root ├── Menu.ArrowTip ├── Menu.Arrow ├── Menu.CheckboxItem ├── Menu.Content ├── Menu.ContextTrigger ├── Menu.Context ├── Menu.Empty ├── Menu.Filter │ └── Menu.FilterInput ├── Menu.Indicator ├── Menu.ItemContext ├── Menu.ItemGroupLabel ├── Menu.ItemGroup ├── Menu.ItemIndicator ├── Menu.ItemText ├── Menu.Item ├── Menu.RadioItemGroup ├── Menu.RadioItem ├── Menu.RootProvider ├── Menu.Separator ├── Menu.TriggerItem ├── Menu.Trigger ``` ## Examples ### Item Selection Use `onSelect` to handle item selection. The callback receives the item's `id`. :component-preview{component="menu" name="controlled"} ### Root Provider An alternative way to control the menu is to use the `RootProvider` component and the `useMenu` hook. This way you can access the state and methods from outside the component. :component-preview{component="menu" name="root-provider"} ### Grouping Use `Menu.ItemGroup` and `Menu.ItemGroupLabel` to organize related menu items. :component-preview{component="menu" name="grouping"} ### Links To render menu items as links, use the `asChild` prop to replace the default element with an anchor tag. :component-preview{component="menu" name="links"} ### Checkbox To add a checkbox to a menu item, use the `Menu.CheckboxItem` component. :component-preview{component="menu" name="checkbox"} ### Radio Group To group radio option items, use the `Menu.RadioItemGroup` component. :component-preview{component="menu" name="radio-group"} ### Context Menu To show the menu when a trigger element is right-clicked, use the `Menu.ContextTrigger` component. Context menus are also opened during a long-press of roughly `700ms` when the pointer is pen or touch. :component-preview{component="menu" name="context"} ### Nested To show a nested menu, render another `Menu` component and use the `Menu.TriggerItem` component to open the submenu. :component-preview{component="menu" name="nested"} ### Menu in Dialog When rendering a menu inside a dialog, use `lazyMount` and `unmountOnExit` to ensure proper cleanup when the dialog closes. :component-preview{component="menu" name="in-dialog"} ### Menu Item Dialog Open a confirmation dialog from a menu item. This pattern is useful for destructive actions like delete that require user confirmation. :component-preview{component="menu" name="item-dialog"} ### Multiple Triggers Share a single menu across multiple trigger elements. Pass a `value` to each `Menu.Trigger` — the menu repositions to whichever trigger is activated. :component-preview{component="menu" name="multiple-triggers"} ### Filterable Use `Menu.Filter` and `Menu.FilterInput` with `useMenuFilterCollection` to filter menu items. Set `:typeahead="false"` on `Menu.Root` so typing goes to the search field instead of menu typeahead. :component-preview{component="menu" name="filterable"} ### Filterable Multiple Combine a filterable menu with `Menu.CheckboxItem` and `:close-on-select="false"` for multi-select. :component-preview{component="menu" name="filterable-multiple"} ## API See [Ark UI Menu docs](https://ark-ui.com/vue/docs/components/menu){rel=""nofollow""} for full props and examples. # Number Input :component-preview{component="number-input" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/number-input.json --- :: ## Usage ```vue ``` ## Composition ```text NumberInput.Root ├── NumberInput.Label ├── NumberInput.Control layout="inset" | "segmented" │ ├── NumberInput.Scrubber optional │ ├── NumberInput.Input │ ├── NumberInput.TriggerGroup optional — stacked steppers (inset only) │ │ ├── NumberInput.IncrementTrigger │ │ └── NumberInput.DecrementTrigger │ ├── NumberInput.IncrementTrigger split steppers — left (+) │ └── NumberInput.DecrementTrigger split steppers — right (−) ├── NumberInput.Context ├── NumberInput.RootProvider └── NumberInput.ValueText ``` ### Layout `NumberInput.Control` accepts a `layout` prop to coordinate styles across parts: - **`inset`** (default) — bordered input with steppers overlaid inside the field. Use `TriggerGroup` to stack increment/decrement on the right. - **`segmented`** — flex row with a shared border on `Control`. Order: optional `Scrubber`, `IncrementTrigger` (+), `Input`, `DecrementTrigger` (−). The value is centered between the two triggers. Padding and focus rings are derived from the chosen layout and child parts — no manual attributes on `Input` are required. ## Examples ### Split Controls Use `layout="segmented"` on `Control`. Place `IncrementTrigger` on the left, `DecrementTrigger` on the right, and optionally add a `Scrubber` before the increment trigger. :component-preview{component="number-input" name="split"} ### Min and Max Pass the `min` prop or `max` prop to set an upper and lower limit for the input. By default, the input will restrict the value to stay within the specified range. :component-preview{component="number-input" name="min-max"} ### Precision In some cases, you might need the value to be rounded to specific decimal points. Set the `formatOptions` and provide `Intl.NumberFormatOptions` such as `maximumFractionDigits` or `minimumFractionDigits`. :component-preview{component="number-input" name="precision"} ### Scrubbing The NumberInput supports the scrubber interaction pattern. To use this pattern, render the `NumberInput.Scrubber` component. It uses the Pointer lock API and tracks the pointer movement. It also renders a virtual cursor which mimics the real cursor's pointer. :component-preview{component="number-input" name="scrubbing"} ### Mouse Wheel The NumberInput exposes a way to increment/decrement the value using the mouse wheel event. To activate this, set the `allowMouseWheel` prop to `true`. :component-preview{component="number-input" name="mouse-wheel"} ### Formatting To apply custom formatting to the input's value, set the `formatOptions` and provide `Intl.NumberFormatOptions` such as `style` and `currency`. :component-preview{component="number-input" name="formatting"} ### Field The `Field` component helps manage form-related state and accessibility attributes of a number input. It includes handling ARIA labels, helper text, and error text to ensure proper accessibility. :component-preview{component="number-input" name="field"} ### Root Provider An alternative way to control the number input is to use the `RootProvider` component and the `useNumberInput` hook. This way you can access the state and methods from outside the component. :component-preview{component="number-input" name="root-provider"} ## API See [Ark UI Number Input docs](https://ark-ui.com/vue/docs/components/number-input){rel=""nofollow""} for full props and examples. # Pagination :component-preview{component="pagination" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/pagination.json --- :: ## Usage ```vue ``` ## Composition ```text Pagination.Root ├── Pagination.Context ├── Pagination.Ellipsis ├── Pagination.FirstTrigger ├── Pagination.Item ├── Pagination.LastTrigger ├── Pagination.NextTrigger ├── Pagination.PrevTrigger ├── Pagination.RootProvider ``` ## Examples ### Controlled To create a controlled Pagination component, manage the state of the current page using the `page` prop and update it when the `onPageChange` event handler is called: :component-preview{component="pagination" name="controlled"} ### Root Provider An alternative way to control the pagination is to use the `RootProvider` component and the `usePagination` hook. This way you can access the state and methods from outside the component. :component-preview{component="pagination" name="root-provider"} ### Customization You can customize the Pagination component by setting various props such as `dir`, `pageSize`, `siblingCount`, and `translations`. Here's an example of a customized Pagination: :component-preview{component="pagination" name="customized"} ### Context Access pagination state and methods with `Pagination.Context` or the `usePaginationContext` hook. You get methods like `setPage`, `setPageSize`, `goToNextPage`, `goToPrevPage`, `goToFirstPage`, `goToLastPage`, as well as properties like `totalPages` and `pageRange`. :component-preview{component="pagination" name="context"} ### Data Slicing Use the `slice()` method to paginate actual data arrays. This method automatically slices your data based on the current page and page size. :component-preview{component="pagination" name="data-slicing"} ### Page Range Display the current page range information using the `pageRange` property. This shows which items are currently visible (e.g., "Showing 1-10 of 100 results"). :component-preview{component="pagination" name="page-range"} ### Page Size Control the number of items per page dynamically using `setPageSize()`. This example shows how to integrate a native select element to change the page size. > **Note:** For uncontrolled behavior, use `defaultPageSize` to set the initial value. For controlled behavior, use `pageSize` and `onPageSizeChange` to programmatically manage the page size. :component-preview{component="pagination" name="page-size"} ### Links Create pagination with link navigation for better SEO and accessibility. This example shows how to use the pagination component with anchor links instead of buttons. :component-preview{component="pagination" name="links"} ## API See [Ark UI Pagination docs](https://ark-ui.com/vue/docs/components/pagination){rel=""nofollow""} for full props and examples. # Password Input :component-preview{component="password-input" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/password-input.json --- :: ## Usage ```vue ``` ## Composition `PasswordInput.Root` wraps the control and input group internally. Compose the input and visibility trigger as direct children: ```text PasswordInput.Root ├── PasswordInput.Input └── PasswordInput.VisibilityTrigger └── PasswordInput.Indicator ├── PasswordInput.Context └── PasswordInput.RootProvider ``` Use [`Field`](https://vuzeno.com/docs/components/field) for labels, helper text, and validation context. ## Examples ### Sizes Use the `size` prop on `PasswordInput.Root` to change the height of the input. :component-preview{component="password-input" name="sizes"} ### Autocomplete Use the `autoComplete` prop to manage autocompletion in the input. - `new-password` — The user is creating a new password. - `current-password` — The user is entering an existing password. :component-preview{component="password-input" name="autocomplete"} ### Controlled Visibility Use the `visible` and `onVisibilityChange` props to control the visibility of the password input. :component-preview{component="password-input" name="controlled-visibility"} ### Root Provider An alternative way to control the password input is to use the `RootProvider` component and the `usePasswordInput` hook. This way you can access the state and methods from outside the component. :component-preview{component="password-input" name="root-provider"} ### Field Combine `PasswordInput` with `Field` to add a label, helper text, and validation context. :component-preview{component="password-input" name="field"} ### Password Managers Use the `ignorePasswordManagers` prop to ignore password managers like 1Password, LastPass, etc. This is useful for non-login scenarios (e.g., "api keys", "secure notes", "temporary passwords"). :component-preview{component="password-input" name="ignore-password-manager"} ### Strength Meter Combine the `PasswordInput` with password strength logic to show visual feedback about password strength. :component-preview{component="password-input" name="strength-meter"} ### Validation Combine with custom validation logic to show real-time feedback. Use the `invalid` prop to indicate validation errors. :component-preview{component="password-input" name="validation"} ## API See [Ark UI Password Input docs](https://ark-ui.com/vue/docs/components/password-input){rel=""nofollow""} for full props and examples. # PhoneField :component-preview{component="phone-field" name="basic"} ## Features - **Auto-formatting** — Phone numbers are formatted in real-time as the user types - **Country selector** — Searchable dropdown with flag display - **Multiple formats** — International, national, or E.164 output - **Country filtering** — Preferred, available, and ignored country lists - **Localization** — Country names displayed in any locale - **Validation utilities** — Ready-to-use validation functions - **Composable** — Flexible slot-based architecture ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/phone-field.json --- :: ## Usage ```vue ``` ## Composition ```text PhoneField.Root ├── PhoneField.CountrySelect ├── PhoneField.Input └── PhoneField.Indicator ``` ## Dependencies This component is built on top of `libphonenumber-js`, for manual installation: ::installation-tabs{:exec='false' command="libphonenumber-js"} :: ## Examples ### With indicator :component-preview{component="phone-field" name="with-indicator"} ### Sizes :component-preview{component="phone-field" name="sizes"} ### Formats The `format` prop controls how the phone number is displayed: :component-preview{component="phone-field" name="formats"} > **Note:** The `modelValue` always stores the full E.164 number regardless of display format. ## Country Filtering Control which countries appear in the selector: | Prop | Purpose | | -------------------- | -------------------------------- | | `preferredCountries` | Shown at the top of the list | | `availableCountries` | Restrict to only these countries | | `ignoredCountries` | Hide specific countries | Countries in `preferredCountries` appear first, followed by remaining `availableCountries`. Any country in `ignoredCountries` is excluded. ## Localization Country names are formatted using `Intl.DisplayNames`. Set the `locale` prop to display names in any language: | Locale | Value | | ------ | ------------------------------------------- | | `en` | United States, France, Germany | | `fr` | États-Unis, France, Allemagne | | `de` | Vereinigte Staaten, Frankreich, Deutschland | ## Validation ### Validation Utilities Three validation functions are exported for different use cases: #### `validatePhoneNumber(phone, country?)` Returns a detailed result object: ```ts type PhoneValidationResult = | { success: true } | { success: false; error: PhoneValidationError } type PhoneValidationError = | "TOO_SHORT" | "TOO_LONG" | "INVALID_COUNTRY" | "INVALID_NUMBER" | "INVALID_FORMAT" ``` #### `isValidPhoneNumber(phone)` Simple boolean check. Returns `true` if the phone number is valid. #### `isValidPhoneNumberForCountry(phone, country)` Boolean check for a specific country. Useful when validating national format numbers. ### Integration with TanStack Form The validation utilities can be used with `@tanstack/vue-form` by calling them inside a field validator: ```vue {9-14} showLineNumbers ``` # Pin Input :component-preview{component="pin-input" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/pin-input.json --- :: ## Usage ```vue ``` ## Composition ```text PinInput.Root ├── PinInput.Label ├── PinInput.Control │ └── PinInput.Input └── PinInput.HiddenInput ``` ## Examples ### Placeholder To customize the default pin input placeholder `○` for each input, pass the placeholder prop and set it to your desired value. :component-preview{component="pin-input" name="placeholder"} ### Blur on Complete By default, the last input maintains focus when filled, and we invoke the `onValueComplete` callback. To blur the last input when the user completes the input, set the prop `blurOnComplete` to `true`. :component-preview{component="pin-input" name="blur-on-complete"} ### OTP Mode To trigger smartphone OTP auto-suggestion, it is recommended to set the `autocomplete` attribute to "one-time-code". The pin input component provides support for this automatically when you set the `otp` prop to `true`. :component-preview{component="pin-input" name="otp-mode"} ### Masking When collecting private or sensitive information using the pin input, you might need to mask the value entered, similar to ``. Pass the `mask` prop to `true`. :component-preview{component="pin-input" name="mask"} ### Field The `Field` component helps manage form-related state and accessibility attributes of a pin input. It includes handling ARIA labels, helper text, and error text to ensure proper accessibility. :component-preview{component="pin-input" name="field"} ### Root Provider An alternative way to control the pin input is to use the `RootProvider` component and the `usePinInput` hook. This way you can access the state and methods from outside the component. :component-preview{component="pin-input" name="root-provider"} ## API See [Ark UI Pin Input docs](https://ark-ui.com/vue/docs/components/pin-input){rel=""nofollow""} for full props and examples. # Popover :component-preview{component="popover" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/popover.json --- :: ## Usage ```vue ``` ## Composition ```text Popover.Root ├── Popover.Anchor ├── Popover.ArrowTip ├── Popover.Arrow ├── Popover.CloseTrigger ├── Popover.Content ├── Popover.Context ├── Popover.Description ├── Popover.Indicator ├── Popover.RootProvider ├── Popover.Title ├── Popover.Trigger ``` ## Examples ### Controlled Use the `open` and `onOpenChange` props to control the open state of the popover. :component-preview{component="popover" name="controlled"} ### Root Provider An alternative way to control the popover is to use the `RootProvider` component and the `usePopover` hook. This way you can access the state and methods from outside the component. :component-preview{component="popover" name="root-provider"} ### Arrow Use `Popover.Arrow` and `Popover.ArrowTip` to render an arrow pointing to the trigger. :component-preview{component="popover" name="arrow"} ### Placement To change the placement of the popover, set the `positioning` prop. :component-preview{component="popover" name="placement"} ### Close Behavior The popover is designed to close on blur and when the esc key is pressed. - To prevent it from closing on blur (clicking or focusing outside), pass the `closeOnInteractOutside` prop and set it to `false`. - To prevent it from closing when the esc key is pressed, pass the `closeOnEsc` prop and set it to `false`. :component-preview{component="popover" name="close-behavior"} ### Modality In some cases, you might want the popover to be modal. This means that it'll trap focus within its content, block scrolling on the body, disable pointer interactions outside the popover, and hide content behind the popover from screen readers. :component-preview{component="popover" name="modality"} ### Anchor Use `Popover.Anchor` to position the popover relative to a different element than the trigger. :component-preview{component="popover" name="anchor"} ### Same Width Use `positioning.sameWidth` to make the popover match the width of its trigger element. :component-preview{component="popover" name="same-width"} ### Dialog Integration When rendering a popover inside a dialog, use `lazyMount` and `unmountOnExit` on the popover root so it is properly unmounted when the dialog closes. :component-preview{component="popover" name="dialog-integration"} ### Nested Popovers can be nested within each other. Each nested popover maintains its own open state and positioning. :component-preview{component="popover" name="nested"} ### Multiple Triggers Share a single popover across multiple trigger elements. Pass a `value` to each `Popover.Trigger` — the popover repositions to whichever trigger is activated without closing. :component-preview{component="popover" name="multiple-triggers"} ## API See [Ark UI Popover docs](https://ark-ui.com/vue/docs/components/popover){rel=""nofollow""} for full props and examples. # Progress Circular :component-preview{component="progress-circular" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/progress-circular.json --- :: ## Usage ```vue ``` ## Composition ```text Progress.Root ├── Progress.Label ├── Progress.CircleContainer │ ├── Progress.Circle │ │ ├── Progress.CircleTrack │ │ └── Progress.CircleRange │ └── Progress.ValueText ├── Progress.Context ├── Progress.RootProvider ├── Progress.Range ├── Progress.Track └── Progress.View ``` ## Examples ### Min and Max By default, the maximum is `100`. If that's not what you want, you can easily specify a different bound by changing the value of the `max` prop. You can do the same with the minimum value by setting the `min` prop. For example, to show the user a progress from `10` to `30`, you can use: :component-preview{component="progress-circular" name="min-max"} ### Indeterminate The progress component is determinate by default, with the value and max set to 50 and 100 respectively. To render an indeterminate progress, you will have to set the `value` to `null`. :component-preview{component="progress-circular" name="indeterminate"} ### Label Add a label to provide additional context for the progress indicator. :component-preview{component="progress-circular" name="label"} ### Root Provider An alternative way to control the progress is to use the `RootProvider` component and the `useProgress` hook. This way you can access the state and methods from outside the component. :component-preview{component="progress-circular" name="root-provider"} ## API See [Ark UI Progress - Circular docs](https://ark-ui.com/vue/docs/components/progress-circular){rel=""nofollow""} for full props and examples. # Progress Linear :component-preview{component="progress-linear" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/progress-linear.json --- :: ## Usage ```vue ``` ## Composition ```text ProgressLinear.Root ├── ProgressLinear.Label ├── ProgressLinear.ValueText ├── ProgressLinear.Track │ └── ProgressLinear.Range └── ProgressLinear.RootProvider ``` ## Examples ### Min and Max By default, the maximum is `100`. If that's not what you want, you can easily specify a different bound by changing the value of the `max` prop. You can do the same with the minimum value by setting the `min` prop. For example, to show the user a progress from `10` to `30`, you can use: :component-preview{component="progress-linear" name="min-max"} ### Indeterminate The progress component is determinate by default, with the value and max set to 50 and 100 respectively. To render an indeterminate progress, you will have to set the `value` to `null`. :component-preview{component="progress-linear" name="indeterminate"} ### Value Text Progress bars can only be interpreted by sighted users. To include a text description to support assistive technologies like screen readers, use the `value` part in `translations`. :component-preview{component="progress-linear" name="value-text"} ### Orientation By default, the progress is assumed to be horizontal. To change the orientation to vertical, set the orientation property in the machine's context to vertical. > Don't forget to change the styles of the vertical progress by specifying its height :component-preview{component="progress-linear" name="vertical"} ### Root Provider An alternative way to control the progress is to use the `RootProvider` component and the `useProgress` hook. This way you can access the state and methods from outside the component. :component-preview{component="progress-linear" name="root-provider"} ## API See [Ark UI Progress - Linear docs](https://ark-ui.com/vue/docs/components/progress-linear){rel=""nofollow""} for full props and examples. # Qr Code :component-preview{component="qr-code" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/qr-code.json --- :: ## Usage ```vue ``` ## Composition ```text QrCode.Root ├── QrCode.Frame │ └── QrCode.Pattern ├── QrCode.Overlay ├── QrCode.DownloadTrigger ├── QrCode.Context └── QrCode.RootProvider ``` ## Examples ### With Overlay You can also add a logo or overlay to the QR code. This is useful when you want to brand the QR code. :component-preview{component="qr-code" name="overlay"} ### Error Correction In cases where the link is too long or the logo overlay covers a significant area, the error correction level can be increased. Use the `encoding.ecc` or `encoding.boostEcc` property to set the error correction level: - `L`: Allows recovery of up to 7% data loss (default) - `M`: Allows recovery of up to 15% data loss - `Q`: Allows recovery of up to 25% data loss - `H`: Allows recovery of up to 30% data loss :component-preview{component="qr-code" name="error-correction"} ### Root Provider An alternative way to control the QR code is to use the `RootProvider` component and the `useQrCode` hook. This way you can access the state and methods from outside the component. :component-preview{component="qr-code" name="root-provider"} ### Download Use the `QrCode.DownloadTrigger` component to allow users to download the QR code as an image. Specify the `fileName` and `mimeType` props for the downloaded file. :component-preview{component="qr-code" name="download"} ## API See [Ark UI Qr Code docs](https://ark-ui.com/vue/docs/components/qr-code){rel=""nofollow""} for full props and examples. # Radio Group :component-preview{component="radio-group" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/radio-group.json --- :: ## Usage ```vue ``` ## Composition ```text RadioGroup.Root ├── RadioGroup.Label ├── RadioGroup.Indicator └── RadioGroup.Item ├── RadioGroup.ItemControl ├── RadioGroup.ItemText └── RadioGroup.ItemHiddenInput ``` ## Examples ### Initial Value To set the radio group's initial value, set the `defaultValue` prop to the value of the radio item to be selected by default. :component-preview{component="radio-group" name="initial-value"} ### Controlled For a controlled Radio Group, the state is managed using the `value` prop, and updates when the `onValueChange` event handler is called: :component-preview{component="radio-group" name="controlled"} ### Root Provider An alternative way to control the radio group is to use the `RootProvider` component and the `useRadioGroup` hook. This way you can access the state and methods from outside the component. :component-preview{component="radio-group" name="root-provider"} ### Disabled To make a radio group disabled, set the `disabled` prop to `true`. :component-preview{component="radio-group" name="disabled"} ## API See [Ark UI Radio Group docs](https://ark-ui.com/vue/docs/components/radio-group){rel=""nofollow""} for full props and examples. # Rating Group :component-preview{component="rating-group" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/rating-group.json --- :: ## Usage ```vue ``` ## Composition ```text RatingGroup.Root ├── RatingGroup.Label └── RatingGroup.Control ├── RatingGroup.Context ├── RatingGroup.Item │ ├── RatingGroup.ItemContext │ └── RatingGroup.ItemIndicator └── RatingGroup.HiddenInput ``` ## Examples ### Controlled When using the `RatingGroup` component, you can use the `value` and `onValueChange` props to control the state. :component-preview{component="rating-group" name="controlled"} ### Root Provider An alternative way to control the rating group is to use the `RootProvider` component and the `useRatingGroup` hook. This way you can access the state and methods from outside the component. :component-preview{component="rating-group" name="root-provider"} ### Field The `Field` component helps manage form-related state and accessibility attributes of a rating group. It includes handling ARIA labels, helper text, and error text to ensure proper accessibility. :component-preview{component="rating-group" name="field"} ### Half Rating Allow `0.5` value steps by setting the `allowHalf` prop to `true`. Ensure to render the correct icon if the `half` value is set in the Rating components render callback. :component-preview{component="rating-group" name="half-rating"} ### Forms To use the rating group within forms, pass the prop `name`. It will render a hidden input and ensure the value changes get propagated to the form correctly. :component-preview{component="rating-group" name="forms"} ### Disabled To make the rating group disabled, set the `disabled` prop to `true`. :component-preview{component="rating-group" name="disabled"} ## API See [Ark UI Rating Group docs](https://ark-ui.com/vue/docs/components/rating-group){rel=""nofollow""} for full props and examples. # Scroll Area :component-preview{component="scroll-area" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/scroll-area.json --- :: ## Usage ```vue ``` ## Composition ```text ScrollArea.Root ├── ScrollArea.Shadow ├── ScrollArea.Viewport │ └── ScrollArea.Content ├── ScrollArea.Scrollbar │ └── ScrollArea.Thumb └── ScrollArea.Corner ``` ## Examples ### Horizontal Configure the scroll area for horizontal scrolling only. :component-preview{component="scroll-area" name="horizontal"} ### Both Directions Enable scrolling in both horizontal and vertical directions. :component-preview{component="scroll-area" name="both-directions"} ### Nested Scroll areas can be nested within each other for complex layouts. :component-preview{component="scroll-area" name="nested"} ### Shadow Add scroll shadows to indicate hidden content. Place `ScrollArea.Shadow` inside `ScrollArea.Root` with a `side` of `top`, `bottom`, `left`, or `right`. The root needs `relative` positioning. :component-preview{component="scroll-area" name="shadow"} ## API See [Ark UI Scroll Area docs](https://ark-ui.com/vue/docs/components/scroll-area){rel=""nofollow""} for full props and examples. # ScrollSpy :component-preview{component="scroll-spy" name="basic"} ## Features - **Active tracking** — Scroll position updates `v-model` from a configurable top offset threshold - **Viewport** — `ScrollSpy.Viewport` is the scroll container that drives tracking - **Zag machine** — Behavior is owned by a Zag.js state machine (`useScrollSpy`, Provider) - **Composable** — Provide active state to Toc (or custom UI) through context ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/scroll-spy.json --- :: ## Usage ```vue ``` ### Root provider Drive the machine yourself with `useScrollSpy` and mount parts under `ScrollSpy.Provider`: ```vue ``` ## Composition ```text ScrollSpy.Root / ScrollSpy.Provider ├── ScrollSpy.Viewport │ └── ScrollSpy.Item └── ScrollSpy.Target ``` ## API Reference ### ScrollSpy.Root | Prop | Type | Default | | ------------- | --------------------------- | ------------ | | `v-model` | `string` | `""` | | `offset` | `number` | `0.25` | | `orientation` | `"vertical" | "horizontal"` | `"vertical"` | `offset` accepts a ratio (`0`–`1`) of the scroll root size, or an absolute pixel value. ### ScrollSpy.Item | Prop | Type | Default | | ------- | -------- | ------- | | `value` | `string` | — | ### ScrollSpy.Target | Prop | Type | Default | | ------- | -------- | ------- | | `value` | `string` | — | Registers an existing document element by id (`document.getElementById(value)`). Use this when sections are rendered outside `ScrollSpy.Viewport` — for example a page sidebar TOC watching article headings. Without a viewport, `ScrollSpy.Root` tracks against the window. ## Notes - Pair with [Toc](https://vuzeno.com/docs/components/toc) for a sidebar rail that follows the active section. - Prefer `ScrollSpy.Viewport` as the scroll container so tracking binds reliably. - Use `ScrollSpy.Target` when you cannot wrap the scrolled content in `ScrollSpy.Item`. - Export `useScrollSpy`, `machine`, `connect`, and `anatomy` for headless composition. # Segment Group :component-preview{component="segment-group" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/segment-group.json --- :: ## Usage ```vue ``` ## Composition ```text SegmentGroup.Root ├── SegmentGroup.Indicator └── SegmentGroup.Item └── SegmentGroup.ItemText ``` ## Examples ### Controlled To create a controlled SegmentGroup component, manage the current selected segment using the `value` prop and update it when the `onValueChange` event handler is called: :component-preview{component="segment-group" name="controlled"} ### Root Provider An alternative way to control the segment group is to use the `RootProvider` component and the `useSegmentGroup` hook. This way you can access the state and methods from outside the component. :component-preview{component="segment-group" name="root-provider"} ### Disabled To disable a segment, simply pass the `disabled` prop to the `SegmentGroup.Item` component: :component-preview{component="segment-group" name="disabled"} ## API See [Ark UI Segment Group docs](https://ark-ui.com/vue/docs/components/segment-group){rel=""nofollow""} for full props and examples. # Select :component-preview{component="select" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/select.json --- :: ## Usage ```vue ``` ## Composition ```text Select.Root ├── Select.Label ├── Select.Trigger │ └── Select.Value ├── Select.Indicators │ ├── Select.ClearTrigger │ └── Select.Indicator ├── Select.Content │ └── Select.ItemGroup │ ├── Select.ItemGroupLabel │ └── Select.Item │ ├── Select.ItemText │ └── Select.ItemIndicator ├── Select.Context └── Select.RootProvider ``` ## Examples ### Controlled Use the `value` and `onValueChange` props to control the selected items. :component-preview{component="select" name="controlled"} ### Root Provider An alternative way to control the select is to use the `RootProvider` component and the `useSelect` hook. This way you can access the state and methods from outside the component. :component-preview{component="select" name="root-provider"} ### Multiple To enable `multiple` item selection: :component-preview{component="select" name="multiple"} ### Grouping Grouping related options can be useful for organizing options into categories. - Use the `groupBy` prop to configure the grouping of the items. - Use the `collection.group()` method to get the grouped items. - Use the `Select.ItemGroup` and `Select.ItemGroupLabel` components to render the grouped items. :component-preview{component="select" name="grouping"} ### Field Use `Field` to manage form state, ARIA labels, helper text, and error text. :component-preview{component="select" name="field"} ### Form Usage Here's an example of integrating the `Select` component with a form. :component-preview{component="select" name="form-usage"} ### Async Loading Here's an example of how to load the items asynchronously when the select is opened. :component-preview{component="select" name="async-loading"} ### Lazy Mount Use `lazyMount` and `unmountOnExit` to control when content is mounted, improving performance. :component-preview{component="select" name="lazy-mount"} ### Select on Highlight Here's an example of automatically selecting items when they are highlighted (hovered or navigated to with keyboard). :component-preview{component="select" name="select-on-highlight"} ### Max Selection Here's an example of limiting the number of items that can be selected in a multiple select. :component-preview{component="select" name="max-selection"} ### Select All Use `selectAll()` from the select context to select all items at once. :component-preview{component="select" name="select-all"} ### Overflow For selects with many items, use `positioning.fitViewport` to ensure the dropdown fits within the viewport. Combine with a max-height on the content to enable scrolling. :component-preview{component="select" name="overflow"} ## API See [Ark UI Select docs](https://ark-ui.com/vue/docs/components/select){rel=""nofollow""} for full props and examples. # Separator :component-preview{component="separator" name="basic"} ## Features - **Horizontal or vertical** — Use the `orientation` prop to switch layout direction - **Styled default** — A subtle `bg-border` line that adapts to orientation - **Customizable** — Override with the `class` prop ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/separator.json --- :: ## Usage ```vue ``` ## Examples ### Vertical Use `orientation="vertical"` for a vertical separator. :component-preview{component="separator" name="vertical"} ### Menu Vertical separators between menu items with descriptions. :component-preview{component="separator" name="menu"} ### List Horizontal separators between list items. :component-preview{component="separator" name="list"} ## API ### Separator | Prop | Type | Default | Description | | ------------- | --------------------------- | -------------- | --------------------------------- | | `orientation` | `"horizontal" | "vertical"` | `"horizontal"` | Layout direction of the separator | | `class` | `string` | — | Additional CSS classes | # Sidebar :component-preview{component="sidebar" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/sidebar.json --- :: ## Overview The Sidebar is a composite layout component built on Ark UI primitives. It supports classic and inset variants, icon collapse with hover flyout submenus, responsive mobile drawer, multiple independent sidebars, and nested usage inside dialogs. ## Composition ```text Sidebar.Provider ├── Sidebar.Root │ ├── Sidebar.Header │ ├── Sidebar.Content │ │ └── Sidebar.Group │ │ ├── Sidebar.GroupLabel │ │ └── Sidebar.GroupContent │ │ └── Sidebar.Menu │ │ ├── Sidebar.MenuItem │ │ │ └── Sidebar.MenuButton │ │ └── Sidebar.MenuSub │ │ ├── Sidebar.MenuSubTrigger │ │ └── Sidebar.MenuSubContent │ ├── Sidebar.Footer │ └── Sidebar.Rail └── Sidebar.Inset └── Sidebar.Trigger ``` ## Theming Sidebar colors use the design system CSS variables: - `--sidebar`, `--sidebar-foreground` - `--sidebar-primary`, `--sidebar-primary-foreground` - `--sidebar-accent`, `--sidebar-accent-foreground` - `--sidebar-border`, `--sidebar-ring` Layout variables are set per sidebar instance: - `--sidebar-width` (default `16rem`) - `--sidebar-width-icon` (default `3rem`) - `--sidebar-width-mobile` (default `18rem` on mobile drawer) Use Tailwind utilities such as `bg-sidebar`, `text-sidebar-foreground`, and `border-sidebar-border`. By default, `Sidebar.Provider` is container-relative (`h-full min-h-0`) and fits inside bounded layouts such as demo cards or dialogs. Pass `full-height` for page-level layouts that should fill the viewport (`min-h-svh`). ## useSidebar `useSidebar(id?)` returns a `ComputedRef`. Access the resolved sidebar with `.value`, or pass an `id` when multiple sidebars are registered. | Property | Type | Description | | --------------- | ---------------------------------- | ------------------------------ | | `state` | `"expanded" | "collapsed"` | Derived open state for styling | | `open` | `Ref` | Desktop expanded state | | `setOpen` | `(boolean) => void` | Set desktop open state | | `openMobile` | `Ref` | Mobile drawer open state | | `setOpenMobile` | `(boolean) => void` | Set mobile drawer state | | `isMobile` | `Ref` | Whether viewport is mobile | | `toggleSidebar` | `() => void` | Toggle desktop or mobile state | | `id` | `string` | Sidebar instance id | | `side` | `"left" | "right"` | Sidebar side | | `variant` | `"sidebar" | "floating" | "inset"` | Visual variant | | `collapsible` | `"offcanvas" | "icon" | "none"` | Collapse behavior | Pass an `id` to `useSidebar("left")` when multiple sidebars are registered. ```ts const sidebar = useSidebar(); sidebar.value?.toggleSidebar(); ``` ## Examples ### Inset variant Visual variant where the main content is wrapped in a padded, rounded container. :component-preview{component="sidebar" name="inset"} ### Icon collapse with hover flyout When collapsed to icon mode, submenus with children open a hover flyout menu instead of hiding nested items. :component-preview{component="sidebar" name="icon"} ### Multiple sidebars Register left and right sidebars with independent state using the `id` prop and `Sidebar.Trigger target`. :component-preview{component="sidebar" name="multiple"} ### Nested in a dialog `Sidebar.Provider` is container-relative by default and fits inside dialogs or other bounded layouts. Pass `full-height` for page-level layouts. :component-preview{component="sidebar" name="dialog"} ### Controlled Control sidebar open state with `v-model:open` on `Sidebar.Root`. :component-preview{component="sidebar" name="controlled"} # Signature Pad :component-preview{component="signature-pad" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/signature-pad.json --- :: ## Usage ```vue ``` ## Composition ```text SignaturePad.Root ├── SignaturePad.ClearTrigger ├── SignaturePad.Context ├── SignaturePad.Control ├── SignaturePad.Guide ├── SignaturePad.HiddenInput ├── SignaturePad.Label ├── SignaturePad.RootProvider ├── SignaturePad.Segment ``` ## Examples ### Image Preview After the user draws a signature, you can display a preview of the signature as an image. This is useful when you want to show the user a preview of the signature before saving it. :component-preview{component="signature-pad" name="image-preview"} ### Field The `Field` component helps manage form-related state and accessibility attributes of a signature pad. It includes handling ARIA labels, helper text, and error text to ensure proper accessibility. :component-preview{component="signature-pad" name="field"} ### Root Provider An alternative way to control the signature pad is to use the `RootProvider` component and the `useSignaturePad` hook. This way you can access the state and methods from outside the component. :component-preview{component="signature-pad" name="root-provider"} ## API See [Ark UI Signature Pad docs](https://ark-ui.com/vue/docs/components/signature-pad){rel=""nofollow""} for full props and examples. # Skeleton :component-preview{component="skeleton" name="basic"} ## Features - **Shimmer** — Light sweep from left to right while content loads - **Shape with classes** — Size and shape via Tailwind utilities (`rounded-full`, fixed width/height) - **Customizable** — Override styles with the `class` prop ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/skeleton.json --- :: ## Usage ```vue ``` ## Examples ### Card Compose multiple skeletons to match a card layout. :component-preview{component="skeleton" name="card"} ## API ### Skeleton | Prop | Type | Default | Description | | ------- | -------- | ------- | ---------------------- | | `class` | `string` | — | Additional CSS classes | # Slider :component-preview{component="slider" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/slider.json --- :: ## Usage ```vue ``` ## Composition ```text Slider.Root ├── Slider.Context ├── Slider.Control ├── Slider.DraggingIndicator ├── Slider.HiddenInput ├── Slider.Label ├── Slider.MarkerGroup ├── Slider.Marker ├── Slider.Range ├── Slider.RootProvider ├── Slider.Thumb ├── Slider.Track ├── Slider.ValueText ``` ## Examples ### Range You can add multiple thumbs to the slider by adding multiple `Slider.Thumb` :component-preview{component="slider" name="range"} ### Marks You can add marks to the slider track by using the `Slider.MarkerGroup` and `Slider.Marker` components. Position the `Slider.Marker` components relative to the track by providing the `value` prop. :component-preview{component="slider" name="marks"} ### Min and Max By default, the minimum is `0` and the maximum is `100`. If that's not what you want, you can easily specify different bounds by changing the values of the `min` and/or `max` props. For example, to ask the user for a value between `-10` and `10`, you can use: :component-preview{component="slider" name="min-max"} ### Granularity By default, the granularity, is `1`, meaning that the value is always an integer. You can change the step attribute to control the granularity. For example, If you need a value between `5` and `10`, accurate to two decimal places, you should set the value of step to `0.01`: :component-preview{component="slider" name="granularity"} ### Change Events When the slider value changes, the `onValueChange` and `onValueChangeEnd` callbacks are invoked. You can use this to set up custom behaviors in your app. :component-preview{component="slider" name="change-events"} ### Orientation By default, the slider is assumed to be horizontal. To change the orientation to vertical, set the orientation property in the machine's context to vertical. In this mode, the slider will use the arrow up and down keys to increment/decrement its value. > Don't forget to change the styles of the vertical slider by specifying its height :component-preview{component="slider" name="orientation"} ### Origin By default, the slider's origin is at the start of the track. To change the origin to the center of the track, set the `origin` prop to `center`. :component-preview{component="slider" name="origin"} ### Root Provider An alternative way to control the slider is to use the `RootProvider` component and the `useSlider` hook. This way you can access the state and methods from outside the component. :component-preview{component="slider" name="root-provider"} ### Dragging Indicator Use the `Slider.DraggingIndicator` component inside `Slider.Thumb` to show a visual indicator while the thumb is being dragged. :component-preview{component="slider" name="dragging-indicator"} ### Thumb Overlap Use the `minStepsBetweenThumbs` prop to prevent range slider thumbs from overlapping. This ensures a minimum gap between thumbs, which is useful for price range filters and similar use cases. :component-preview{component="slider" name="thumb-overlap"} ### Thumb Collision Use the `thumbCollisionBehavior` prop to control how thumbs behave when they collide during pointer interactions. Supported values are `push` (default), `swap`, and `none`. :component-preview{component="slider" name="thumb-collision"} ## API See [Ark UI Slider docs](https://ark-ui.com/vue/docs/components/slider){rel=""nofollow""} for full props and examples. # Splitter :component-preview{component="splitter" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/splitter.json --- :: ## Usage ```vue ``` ## Composition ```text Splitter.Root ├── Splitter.Context ├── Splitter.Panel ├── Splitter.ResizeTrigger ├── Splitter.ResizeTriggerIndicator ├── Splitter.RootProvider ``` ## Examples ### Context Access the splitter's API with `Splitter.Context` or the `useSplitterContext` hook. This lets you resize panels programmatically: :component-preview{component="splitter" name="context"} ### Vertical By default, the Splitter component is horizontal. If you need a vertical splitter, use the `orientation` prop: :component-preview{component="splitter" name="vertical"} ### Collapsible Panels To make a panel collapsible, set the `collapsible` prop to `true` on the panel you want to make collapsible. Additionally, you can use the `collapsedSize` prop to set the size of the panel when it's collapsed. > This can be useful for building sidebar layouts. :component-preview{component="splitter" name="collapsible"} ### Multiple Panels Here's an example of how to use the `Splitter` component with multiple panels. :component-preview{component="splitter" name="multiple-panels"} ### Root Provider An alternative way to control the splitter is to use the `RootProvider` component and the `useSplitter` hook. This way you can access the state and methods from outside the component. :component-preview{component="splitter" name="root-provider"} ### Resize Indicator Use the `Splitter.ResizeTriggerIndicator` component to show a visual indicator on the resize handle. :component-preview{component="splitter" name="resize-indicator"} ### Dynamic Collapsible Use the `collapsePanel()` and `expandPanel()` methods to programmatically control panel collapse based on viewport size. This is useful for responsive sidebar layouts that collapse on smaller screens. :component-preview{component="splitter" name="dynamic-collapsible"} ### Nested Nest splitters to build grid-like layouts. Use `createSplitterRegistry()` to create a shared registry between splitter instances — this enables multi-drag at intersection points where horizontal and vertical splitters meet. :component-preview{component="splitter" name="nested"} ## API See [Ark UI Splitter docs](https://ark-ui.com/vue/docs/components/splitter){rel=""nofollow""} for full props and examples. # Steps :component-preview{component="steps" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/steps.json --- :: ## Usage ```vue ``` ## Composition ```text Steps.Root ├── Steps.CompletedContent ├── Steps.Content ├── Steps.Context ├── Steps.Indicator ├── Steps.ItemContext ├── Steps.Item ├── Steps.List ├── Steps.NextTrigger ├── Steps.PrevTrigger ├── Steps.Progress ├── Steps.RootProvider ├── Steps.Separator ├── Steps.Trigger ``` ## Examples ### Controlled Using the `RootProvider` component, you can control the active step by using the `step` prop and handling the `onStepChange` event. :component-preview{component="steps" name="controlled"} ### Root Provider An alternative way to control the steps is to use the `RootProvider` component and the `useSteps` hook. This way you can access the state and methods from outside the component. :component-preview{component="steps" name="root-provider"} ### Vertical Use the `orientation` prop to display the steps vertically. :component-preview{component="steps" name="vertical"} ### Circular Progress Show a circular progress indicator with the current step count (`X/X`), plus the title and description of the active step. :component-preview{component="steps" name="circular-progress"} ### Linear Progress Place a linear progress bar above the steps, synced to the completion percentage. The step list below omits separators. :component-preview{component="steps" name="linear-progress"} ## API See [Ark UI Steps docs](https://ark-ui.com/vue/docs/components/steps){rel=""nofollow""} for full props and examples. # Switch :component-preview{component="switch" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/switch.json --- :: ## Usage ```vue ``` ## Composition ```text Switch.Root ├── Switch.Context ├── Switch.Control ├── Switch.HiddenInput ├── Switch.Label ├── Switch.RootProvider ├── Switch.Thumb ``` ## Examples ### Sizes Use the `size` prop on `Switch.Root` to change the size of the switch. :component-preview{component="switch" name="sizes"} ### Controlled For a controlled Switch component, the state of the toggle is managed using the checked prop, and updates when the `onCheckedChange` event handler is called: :component-preview{component="switch" name="controlled"} ### Root Provider An alternative way to control the switch is to use the `RootProvider` component and the `useSwitch` hook. This way you can access the state and methods from outside the component. :component-preview{component="switch" name="root-provider"} ### Field The `Field` component helps manage form-related state and accessibility attributes of a switch. It includes handling ARIA labels, helper text, and error text to ensure proper accessibility. :component-preview{component="switch" name="field"} ### Context Access the switch's state with `Switch.Context` or the `useSwitchContext` hook. This lets you customize the component based on its current state: :component-preview{component="switch" name="context"} ## API See [Ark UI Switch docs](https://ark-ui.com/vue/docs/components/switch){rel=""nofollow""} for full props and examples. # Table :component-preview{component="table" name="basic"} ## Features - **Composable** — Flexible slot-based layout with `Table.Header`, `Table.Body`, `Table.Footer`, `Table.Row`, `Table.Head`, and `Table.Cell` - **Scrollable** — Root wraps the table in an overflow container for wide datasets - **Empty state** — Built-in `Table.Empty` for zero-result views - **Customizable** — Override any part with the `class` prop ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/table.json --- :: ## Composition ```text Table.Root ├── Table.Caption ├── Table.Header │ └── Table.Row │ └── Table.Head ├── Table.Body │ └── Table.Row │ └── Table.Cell └── Table.Footer └── Table.Row └── Table.Cell ``` ## Usage ```vue ``` ## Examples ### Empty state Use `Table.Empty` when there are no rows to display. :component-preview{component="table" name="empty"} ### With filters Compose [Filters](https://vuzeno.com/docs/components/filters) above the table to narrow rows client-side. Use `Table.Empty` when nothing matches. :component-preview{component="table" name="with-filters"} # Tabs :component-preview{component="tabs" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/tabs.json --- :: ## Usage ```vue ``` ## Composition ```text Tabs.Root ├── Tabs.TabList │ ├── Tabs.TabTrigger │ ├── Tabs.TabTriggerIndicator │ └── Tabs.TabIndicator ├── Tabs.TabContent ├── Tabs.Context └── Tabs.RootProvider ``` ## Examples ### Controlled To create a controlled Tabs component, manage the current selected tab using the `value` prop and update it when the `onValueChange` event handler is called. :component-preview{component="tabs" name="controlled"} ### Root Provider An alternative way to control the tabs is to use the `RootProvider` component and the `useTabs` hook. This way you can access the state and methods from outside the component. :component-preview{component="tabs" name="root-provider"} ### Indicator To provide a visual cue for the selected tab, use the `Tabs.TabIndicator` component with `Tabs.TabTriggerIndicator` triggers. :component-preview{component="tabs" name="indicator"} ### Disabled To disable a tab, pass the `disabled` prop to the `Tabs.TabTrigger` component. :component-preview{component="tabs" name="disabled"} ### Vertical The default orientation of the tabs is `horizontal`. To change the orientation, set the `orientation` prop to `vertical`. :component-preview{component="tabs" name="vertical"} ### Lazy Mount Lazy mounting renders tab content only when the tab is first activated. Use `lazy-mount` and `unmount-on-exit` on `Tabs.Root` to free resources when a tab is deactivated. :component-preview{component="tabs" name="lazy-mount"} ### Manual Activation By default, the tab can be selected when it receives focus from either the keyboard or pointer interaction. With `activation-mode="manual"`, the tab is selected with the Enter key or by clicking on the tab. :component-preview{component="tabs" name="manual-activation"} ### Links Use the `as-child` prop to render tab triggers as anchor links. This is useful for SEO and allows tabs to work with browser navigation. :component-preview{component="tabs" name="links"} ## API See [Ark UI Tabs docs](https://ark-ui.com/vue/docs/components/tabs){rel=""nofollow""} for full props and examples. # Tags Input :component-preview{component="tags-input" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/tags-input.json --- :: ## Usage ```vue ``` ## Composition ```text TagsInput.Root ├── TagsInput.ClearTrigger ├── TagsInput.Context ├── TagsInput.Control ├── TagsInput.HiddenInput ├── TagsInput.Input ├── TagsInput.ItemContext ├── TagsInput.ItemDeleteTrigger ├── TagsInput.ItemInput ├── TagsInput.ItemPreview ├── TagsInput.ItemText ├── TagsInput.Item ├── TagsInput.Label ├── TagsInput.RootProvider ``` ## Examples ### Controlled Use the `value` and `onValueChange` props to programmatically control the tags input's state. This allows you to manage the tags array externally and respond to changes. :component-preview{component="tags-input" name="controlled"} ### Controlled Input Value Use the `inputValue` and `onInputValueChange` props to control the text input field independently. This is useful for clearing the input or pre-filling it programmatically. :component-preview{component="tags-input" name="controlled-input-value"} ### Root Provider An alternative way to control the tags input is to use the `RootProvider` component and the `useTagsInput` hook. This way you can access the state and methods from outside the component. :component-preview{component="tags-input" name="root-provider"} ### Field The `Field` component helps manage form-related state and accessibility attributes of a tags input. It includes handling ARIA labels, helper text, and error text to ensure proper accessibility. :component-preview{component="tags-input" name="field"} ### Max Tags To limit the number of tags within the component, you can set the `max` property to the limit you want. The default value is `Infinity`. :component-preview{component="tags-input" name="max-tags"} ### Custom Delimiter Use the `delimiter` prop with a regex pattern to specify multiple characters that can separate tags. By default, only the Enter key creates tags. :component-preview{component="tags-input" name="custom-delimiter"} ### Disabled Use the `disabled` prop to make the tags input non-interactive. Users won't be able to add, remove, or edit tags. :component-preview{component="tags-input" name="disabled"} ### Invalid Use the `invalid` prop to mark the tags input as invalid for form validation purposes. :component-preview{component="tags-input" name="invalid"} ### Max Length Use the `maxLength` prop to limit the number of characters allowed per tag. This prevents users from creating overly long tags. :component-preview{component="tags-input" name="max-length"} ### Read-only Use the `readOnly` prop to make tags visible but not editable. Users can view tags but cannot add, remove, or modify them. :component-preview{component="tags-input" name="read-only"} ### Validation Before a tag is added, the `validate` function is called to determine whether to accept or reject a tag. :component-preview{component="tags-input" name="validation"} ### Blur behavior When the tags input is blurred, you can configure the action the component should take by passing the `blurBehavior` prop. - `add` — Adds the tag to the list of tags. - `clear` — Clears the tags input value. :component-preview{component="tags-input" name="blur-behavior"} ### Paste behavior To add a tag when a arbitrary value is pasted in the input element, pass the `addOnPaste` prop. When a value is pasted, the component will: - check if the value is a valid tag based on the `validate` option - split the value by the `delimiter` option passed :component-preview{component="tags-input" name="paste-behavior"} ### Disable Editing by default the tags can be edited by double-clicking on the tag or focusing on them and pressing Enter. To disable this behavior, pass `editable={false}` :component-preview{component="tags-input" name="disable-editing"} ### Programmatic Control Use the `useTagsInput` hook with `RootProvider` to access the component's API methods like `addValue()`, `setValue()`, and `clearValue()` for full programmatic control. :component-preview{component="tags-input" name="programmatic-control"} ### Sanitize Value Use the `sanitizeValue` prop to normalize tag values before they're added. This runs on every new tag — useful for trimming whitespace, converting to lowercase, or any other formatting you need. :component-preview{component="tags-input" name="sanitize-value"} ### Autocomplete Combine TagsInput with Autocomplete to create an autocomplete tags input. This pattern uses shared IDs between both components and the `asChild` prop to compose the inputs together. :component-preview{component="tags-input" name="autocomplete"} ## API See [Ark UI Tags Input docs](https://ark-ui.com/vue/docs/components/tags-input){rel=""nofollow""} for full props and examples. # Textarea :component-preview{component="textarea" name="basic"} ## Installation Install from the Vuzeno registry: ::installation-tabs --- exec: true command: shadcn-vue@latest add https://vuzeno.com/r/textarea.json --- :: ## Usage ```vue